3

I have a code for ATmega written in C and compiled with GCC compiler.

Some data need to be stored in EEPROM so I add these declarations:

enter image description here

After I read EEPROM I found that data placed in some weird way. After some investigation I found this text in .map file (one of many produced by the tool chain):

enter image description here

As you can see compiler put data in reverse order.

Of course I could reverse declaration and enjoy further coding but this is something unexpected so I'm afraid to face with any other unexpected behaviour until i don't understand why compiler did so.

Any thoughts?

Vlada Katlinskaya
  • 991
  • 1
  • 10
  • 26
  • 1
    A compiler/linker is free to place the variables wherever it wants. The question is rather why you expect a certain order, or if the order matters to your program? – Lundin Dec 22 '15 at 07:20
  • 1
    It (order) make sense for me as I'm reading EEPROM afterwords and making some analysis of the data. So the order is essential for me :( – Vlada Katlinskaya Dec 22 '15 at 07:31
  • If the order matters (for example if you wish to read/program the eeprom through some external tool) then you really need to manually specify at which address every single variable is allocated at. There should be some system-specific way to do that: some `#pragma` or "__declspec" or whatever it might be called on your system. – Lundin Dec 22 '15 at 07:37
  • @Lundin I mad for this behaviour :((((((( Now I aware of that the compiler is free to locate variables wherever it desire. However I don't see any reason to obfuscate data in this particular case :( I'd understand if some padding would be applied, but this unexpected reverse is like a dirty trick. Specifying the direct address is not the best way generally as I will need to care of overlaps (and any other problems) by my self which is easy in my case but can be tricky and unreliable in bigger projects. Thank you for the #pragma idea (I will try to find the syntax). – Vlada Katlinskaya Dec 22 '15 at 07:51
  • 1
    I remember avr-gcc reversed the order of `EEMEM` objects in memory vs their declaration appearance around avr-gcc 4.6. As others said you cannot assume any order. – ouah Dec 22 '15 at 09:33

1 Answers1

2

As @Lundin stated, global variables aren't required to be allocated consecutively.

You could use the feature of struct that its members always are allocated in the same order they are specified.
From the C11 standard, §6.7.2.1.15:

Within a structure object, the non-bit-field members and the units in which bit-fields reside have addresses that increase in the order in which they are declared.

Be aware of padding, though!

Community
  • 1
  • 1
cadaniluk
  • 15,027
  • 2
  • 39
  • 67