Variable names in C

Thread Starter

Ian0

Joined Aug 7, 2020
13,126
I have a number of variables (about 128) that I want to be able to refer to by name, and also to be able to send via the UART (which would be much easier if they were in an array).
My first thought - ENUM the variable names, and use them as the indices of the array. All went well, until I was debugging the program (in Eclipse, Renesas's version of Eclipse "E2Studio" to be precise)
The usual "click on the variable name to see the value" no longer works, it just tells me that it is an ENUM and doesn't even give the number that it was enumerated to. So debugging quickly becomes next-to-impossible.
So this is an Eclipse problem, not a C problem, but is there a way around it? Or is there a better way of giving variables both names and indices?
 

joeyd999

Joined Jun 6, 2011
6,269
I have a number of variables (about 128) that I want to be able to refer to by name, and also to be able to send via the UART (which would be much easier if they were in an array).
My first thought - ENUM the variable names, and use them as the indices of the array. All went well, until I was debugging the program (in Eclipse, Renesas's version of Eclipse "E2Studio" to be precise)
The usual "click on the variable name to see the value" no longer works, it just tells me that it is an ENUM and doesn't even give the number that it was enumerated to. So debugging quickly becomes next-to-impossible.
So this is an Eclipse problem, not a C problem, but is there a way around it? Or is there a better way of giving variables both names and indices?
Why is an array not appropriate?
 

Thread Starter

Ian0

Joined Aug 7, 2020
13,126
Why is an array not appropriate?
From a C point of view it is perfect, but the debugger spoils it.
I click on data[voltage] and all it tell me is that voltage is an enum.
If i had written data[3] then I can see the value.
 

BobTPH

Joined Jun 5, 2013
11,503
You could use a union to overlay the individual names with an array:
Code:
union {
    int a[3];
    struct {
         int a, b, c;
     } v;
 } vars;
…
// vars.v.c and vars.a[2] are the same
 

nsaspook

Joined Aug 27, 2009
16,298

Thread Starter

Ian0

Joined Aug 7, 2020
13,126
It seems to be a common debugger shortcoming. With GDB you could use artificial arrays to look at sets of memory index locations.
https://forum.qt.io/topic/153497/qt...s-when-used-as-array-indexes-instead-of-0-1-2
https://opensource.apple.com/source/gdb/gdb-250/doc/gdb.html/gdb_9.html
So it really is a problem, not just my lack of complete knowledge about C.
That’s good to know, but not helpful.

I did discover that if I made it into a structure that was just a single int16_t then it works.
i.e.
my data[voltage] is then written data[voltage].value and clicking on the word value displays the data, but it’s hardly tidy programming.
 

Thread Starter

Ian0

Joined Aug 7, 2020
13,126
After a bit of thought. . .
The program access the variable by name far more often than as an array, so that needs to work best.
So I made a structure.
with a structure pointer.
As they are all int16_t I can then access them using pointers when I need to read them as an array. (I approached C from learning my trade in assembler, so that just seems entirely logical to an assembler programmer)

I did learn something new (or new to me) in the process . . It is possible to make a structure pointer to the inner of two nested structures.
 

nsaspook

Joined Aug 27, 2009
16,298
After a bit of thought. . .
The program access the variable by name far more often than as an array, so that needs to work best.
So I made a structure.
with a structure pointer.
As they are all int16_t I can then access them using pointers when I need to read them as an array. (I approached C from learning my trade in assembler, so that just seems entirely logical to an assembler programmer)

I did learn something new (or new to me) in the process . . It is possible to make a structure pointer to the inner of two nested structures.
The freedom to use bare memory semantics in a HLL context is what makes C a great low level language. It's both a language blessing and a minefield of implementation dependant behavior.
 

Thread Starter

Ian0

Joined Aug 7, 2020
13,126
The freedom to use bare memory semantics in a HLL context is what makes C a great low level language. It's both a language blessing and a minefield of implementation dependant behavior.
It would seem that the world of microcontrollers is dominated by Eclipse, which uses the GNU compiler, so “implementation dependent” isn’t too much of a problem. I do prefer uint16_t etc. to int and short, because they are less ambiguous, but, I suppose that there is nothing stopping the compiler deciding that a uint16_t should be stored in a 32-bit word.
 

WBahn

Joined Mar 31, 2012
32,796
After a bit of thought. . .
The program access the variable by name far more often than as an array, so that needs to work best.
So I made a structure.
with a structure pointer.
As they are all int16_t I can then access them using pointers when I need to read them as an array. (I approached C from learning my trade in assembler, so that just seems entirely logical to an assembler programmer)

I did learn something new (or new to me) in the process . . It is possible to make a structure pointer to the inner of two nested structures.
I'm not sure I'm envisioning exactly what you are doing. Is it something along these lines:

Code:
struct s
{
   int16_t a, b;
};

struct s *fred;
int16_t *sue = fred;

fred->a = 42;
sue[1] = 43;
If so, then be aware that the compiler is free to add padding to the internal layout of a structure so as to align the members on its preferred boundaries, which might be 32-bit. So fred.b might be at sue[2].
 

Thread Starter

Ian0

Joined Aug 7, 2020
13,126
I'm not sure I'm envisioning exactly what you are doing. Is it something along these lines:

Code:
struct s
{
   int16_t a, b;
};

struct s *fred;
int16_t *sue = fred;

fred->a = 42;
sue[1] = 43;
If so, then be aware that the compiler is free to add padding to the internal layout of a structure so as to align the members on its preferred boundaries, which might be 32-bit. So fred.b might be at sue[2].
That was exactly my plan. I could have made a union with an array of int16_t, but the variable names involve more typing.
The compiler aligns int16_t to .align 1 boundaries, and int32_t to .align 2 boundaries.
 

BobTPH

Joined Jun 5, 2013
11,503
Or you could have used the method I suggested and used macros for the variable names:

#define a vars.v.a
#define b vars.v.b


No need for the extra overhead of a pointer that way.

I was given access to the source code of a very large successful commercial database program in a locked room in order to debug a compiler problem, and it used macros like that extensively.
 

WBahn

Joined Mar 31, 2012
32,796
That was exactly my plan. I could have made a union with an array of int16_t, but the variable names involve more typing.
The compiler aligns int16_t to .align 1 boundaries, and int32_t to .align 2 boundaries.
I'm not aware of anything that requires this. Could you provide a reference to where the C language requires a compiler to do this?
 

Thread Starter

Ian0

Joined Aug 7, 2020
13,126
I'm not aware of anything that requires this. Could you provide a reference to where the C language requires a compiler to do this?
I don’t mean that it was required to do that. I just observed that it did.
 

Thread Starter

Ian0

Joined Aug 7, 2020
13,126
Or you could have used the method I suggested and used macros for the variable names:

#define a vars.v.a
#define b vars.v.b


No need for the extra overhead of a pointer that way.

I was given access to the source code of a very large successful commercial database program in a locked room in order to debug a compiler problem, and it used macros like that extensively.
That would be fine, provided that the debugger will expand the macro. As it refused to expand the enum, which is where this thread started, I’m not holding my breath, but it’s a quick enough edit to try.
 

nsaspook

Joined Aug 27, 2009
16,298
It would seem that the world of microcontrollers is dominated by Eclipse, which uses the GNU compiler, so “implementation dependent” isn’t too much of a problem. I do prefer uint16_t etc. to int and short, because they are less ambiguous, but, I suppose that there is nothing stopping the compiler deciding that a uint16_t should be stored in a 32-bit word.
Your world of microcontrollers is dominated by Eclipse. :D It's just a warning that GNU (and every other compiler designed for embedded applications) compilers have padding and packing #pragma and attributes to handle “implementation dependent” behaviours (for speed in access and addressing) even in the same family of processors.

Padding becomes critical with things like memory mapped interfaces where you can have various variable types (and byte sizes) and needed alignments in the same set of structures.

http://www.catb.org/esr/structure-packing/
 

Thread Starter

Ian0

Joined Aug 7, 2020
13,126
That would be fine, provided that the debugger will expand the macro. As it refused to expand the enum, which is where this thread started, I’m not holding my breath, but it’s a quick enough edit to try.
It doesn’t.
 
Top