1

In xxx.h file I have declaration:

const struct MenuItem MenuItemA;

in xxx.c file I have definition:

const struct MenuItem MenuItemA PROGMEM = {textA, MenuItemAFunction, &MenuItemB, 0};

I also include xxx.h file in my main.c file. While building the project i get this warning:

uninitialized variable 'MenuItemA' put into program memory area [-Wuninitialized]

When I had declaration and definition in the same .c file everything was OK, I have no idea what is wrong now.

Al Bundy
  • 653
  • 1
  • 6
  • 22
  • 2
    In the header file you *define* the variable, which means that every file that includes the header file will have that variable defined. Make it `extern` so it's only *declared* in the header file and it should work better. – Some programmer dude Apr 06 '14 at 15:26
  • Ok now it is ok, thanks. I needed predeclaration and i thought that **const struct MenuItem MenuItemA;** in the header file is a declaration. Why is it not ? I do not define any values. – Al Bundy Apr 06 '14 at 15:58
  • Ok I checked it in the Stephen Prata book about C programming and now I'm sure that **const struct MenuItem MenuItemA;** in the header file is a declaration so I do not understand the error. Can anyone explain it to me ? – Al Bundy Apr 06 '14 at 17:10

2 Answers2

1

Joachim is correct, ALL definitions in header files need an extern - otherwise every time you use the header (in a different source file) you'll create another copy of the variable. To answer your original question, I suspect the variable is in the code section because it is constant, if you remove the const it'll go into the BSS or DATA section depending on how it's defined. But you're main problem is the lack of an extern

Anonymouse
  • 935
  • 9
  • 20
  • Yeah but according to all basic C books **const struct MenuItem MenuItemA;** is a declaration, so including xxx.h file in different source files should not make any errors. Is variable (after declaration) initialized depends on where it goes (code section, bss or data section) ? – Al Bundy Apr 06 '14 at 19:48
  • Nope... http://stackoverflow.com/questions/1410563/what-is-the-difference-between-a-definition-and-a-declaration. Uninitialised variables go in bss, initialised in data. Const variable tend to go into rodata, but can also go in code – Anonymouse Apr 06 '14 at 20:22
  • "otherwise every time you use the header (in a different source file) you'll create another copy of the variable" That wouzld be true if it was preceded by `static`. The way it is used here is called "tentative definition": an uninitialized definition is seen by the linker and valid as long as it is not overridden by a definition which is explicitly defined. – glglgl Nov 21 '15 at 17:22
  • And the variable is in the code section because it is explicitly stated that it be put into `PROGMEM`, not because of the `const`... – glglgl Nov 21 '15 at 17:31
1

As you say, it is not an error, but merely a warning about wasting precious flash memory for uninitialized variables.

If it is indeed uninitialized, there seems to be no need to put it explicity into progmem as it is constant there and cannot be overwritten (easily) during program run.

The way you use it - have a tentative definition in all files which include the header file and define it in one file will make the compilation of the other files complain about exacly this. (This would better be a link time warning instead of a compile time warning...)

(BEGIN of long BLAH)


I just ran into the same issue: I want to create a "plugin" framework where the user of my library can choose whether to add a certain function pointer as a "plugin": in my library's header file, I have a

extern some_type * const PROGMEM my_array[];

and a

#define enable_my_stuff() some_type * const PROGMEM my_array[2] = {something_of_some_type, NULL}

while my library's C file has a

// Tentative definition which is used when nothing else is there.
some_type * const PROGMEM my_array[2];

This way I have two cases: either no one uses enable_my_stuff() and my array is empty (that's ok, but 4 bytes are wasted) or enable_my_stuff() is used, the extended functionality is activated and the array content reflects this.

It works, but I get exactly the warning as above. As it annoys me, I'm probably going to implement it in a different way.


(END of long BLAH)

Community
  • 1
  • 1
glglgl
  • 89,107
  • 13
  • 149
  • 217