Re: Order of variables in specific sections when enabling optimization in gcc

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On 07/03/2019 14:56, Freddie Chopin wrote:
> On Thu, 2019-03-07 at 14:05 +0100, David Brown wrote:
>> The -fno-toplevel-reorder switch can be handy too - it will stop
>> re-ordering within a translation unit.
> 
> Great - I'll try that soon (; This seems to be what I was looking for!
> 

I'd recommend putting it as:

	#pragma GCC optimize ("-fno-toplevel-reorder")

in the source code defining your data.  That way it should work no
matter what switches are used.  (I hope that option is allowed in the
pragma - not all options are.)

>> However, if you are using LTO or -fdata-sections and the
>> --gc-sections linker option, variables that are not needed get
>> eliminated.  (Note that this could happen even if they are actually
>> used, if the compiler can figure out that the storage is not needed.)
> 
> --gc-sections and -fdata-sections does not affect variables for which I
> explicity set the section. They are not removed, even if not used (I'm
> not using LTO).
> 

-fdata-sections won't affect your explicit sections.  (This is a setting
that is often used in embedded systems, as a way of minimising sizes,
but it actually adds significantly to code size and run-time on devices
like ARM Cortex.)  I don't know if --gc-sections affects such sections,
but if you use at least one variable in the section, then it won't be
"garbage collected" anyway.

>> I have seen people try to use section attributes and careful linker
>> setups to get consistent memory layouts between program versions.
>> (Usually it is eeprom, rather than battery backed ram, but the
>> principle
>> is the same.)  It is often possible to get a reasonable solution - it
>> is
>> rarely possible to get a good and reliable solution that caters for
>> all
>> possibilities.  Typically things break down when you want to add a
>> new
>> variable.
> 
> I would think that as long as all of such variables are in single
> source file and the compiler keeps the order (whatever order that is)
> then everything will be fine.

Yes, it would be.  But it's very easy to accidentally mess up your
variables when trying to add new ones or change existing ones.

A particular benefit I find with the struct solution is that you can use
_Static_assert to check that the offsets of the different parts are as
you expect them to be.  When you change things - replacing padding and
"reserved" space with real variables - you will be glad of this extra check.

Another thing you can do with struct's is to have multiple struct types
- you can have "struct params_v1" now, and later have "struct params_v2"
for a new version.  You can use pointers to these types to read off the
"param structure version number" item and then update the old structure
to the new one when you first run the new software.  This can be a lot
harder when the variables are defined independently.

The struct method also makes it vastly easier to have multiple sets of
parameters - perhaps a factory default set in flash.  Reset to default
then becomes a nice memcpy from an initialised const struct.  Doing this
with individual items in a special section in ram means duplicating
these items as const items within a special section in flash - it's a
maintenance problem waiting to happen.  And there is no equivalent of
"-Wmissing-field-initializers" to help you spot your bugs.

> 
>> My personal preference is to make a struct definition that holds
>> /all/
>> the variables in the special area.  This makes it easy to track, and
>> easy to be sure that you have everything where you expect it.  My
>> struct
>> here starts with some metadata - an indicator of the program type (if
>> you have more than one program for the same card), a struct version
>> number (so that a new program version can re-use old data while
>> knowing
>> that new data might not be properly initialised), and typically
>> stamps
>> and CRC's for allowing multiple versions of the data.  (That is
>> relevant
>> for eeproms that take some time to store the data, when you might
>> have a
>> power fail during write - it is less relevant for battery backed
>> ram.)
> 
> Yes, as I wrote in another reply, this indeed is also an option, but I
> would prefer something simpler if possible (; I'm fine with keeping the
> variables in simple source file, but possibly as "independent" objects,
> so that I can have separate header for each variable.
> 

It is not worth it, IMHO - the struct solution gives too many benefits.
 But that might be influenced by my preference for organising code and
headers - I would not normally be putting these items in different
headers anyway.

> Regards,
> FCh
> 
> 




[Index of Archives]     [Linux C Programming]     [Linux Kernel]     [eCos]     [Fedora Development]     [Fedora Announce]     [Autoconf]     [The DWARVES Debugging Tools]     [Yosemite Campsites]     [Yosemite News]     [Linux GCC]

  Powered by Linux