Watch, Follow, &
Connect with Us

For forums, blogs and more please visit our
Developer Tools Community.


Welcome, Guest
Guest Settings
Help

Thread: data alignment problem std::list forces BYTE aligment



Permlink Replies: 4 - Last Post: Dec 21, 2014 10:08 PM Last Post By: Remy Lebeau (Te...
Dan Ambrose

Posts: 87
Registered: 12/11/03
data alignment problem std::list forces BYTE aligment
Click to report abuse...   Click to reply to this thread Reply
  Posted: Dec 20, 2014 6:04 AM
I'm using C++ Builder XE5

#include <list>

Changes the data alignment. std::list forces BYTE alignment
This causes problems.

I've been investigating this problem for several days. It all started when I enabled codeguard. You get a GPF in constructor saying the size was 4 bytes too small.
First thing I did was checked the data alignment.
Project | Options | Compiler | Data Alignment
It was at the default Quad Word.
I changed it to byte for all platforms. Rebuilt and test. No change.

Before I found the problem I made a unit that gets included and used by other modules. In that unit I put a static function Widget::getsize to return sizeof(Widget);
In other modules I directly call sizeof(Widget) and compare it to the static function Widget::getsize
Sometimes they match. When they don't the static function is always 4 bytes smaller.

You google and get back a punch of hits saying to change the 'Zero length empty base class'. I tried changing both of them. No difference.

So I pasted a list every included header file from all the other modules in my test unit. Then systematically tested each one within
the test unit itself. To find out what was changing the alignment.
I discovered that
#include <list>
Forces the alignment to BYTE.

It doesn't matter what you set Project | Options | Compiler | Data Alignment
It gets ignored.

So that has brought me here asking for help.

Is there some known rule about <list> that changes alignment to byte ?

Is there some rule about the order of include when using the VCL ?

Could this be some bug in the dinkumware header file ?

Is this discussed anywhere in the embarcadero documentation ?

Books - I have "The C++ Standard Library" by Nicolai Josuttis
I bought that in 1999 and read it back then when I was developing a project.
Its been 14 years since I read it. If there is anything in there that I forgot please do tell me about it.

Edited by: Dan Ambrose on Dec 20, 2014 8:45 AM
Remy Lebeau (Te...


Posts: 9,447
Registered: 12/23/01
Re: data alignment problem std::list forces BYTE aligment [Edit]
Click to report abuse...   Click to reply to this thread Reply
  Posted: Dec 20, 2014 11:30 AM   in response to: Dan Ambrose in response to: Dan Ambrose
Dan wrote:

I discovered that

#include <list>

Forces the alignment to BYTE.

The STL as a whole forces its own alignment (via "#pragma option push -a")
and restores the original alignment when done (via "#pragma option pop"),
and has done so for many years. In earlier versions, the two pragmas were
in different header files (_prolog.h and _epilog.h) so the compiler would
issue "W8059 Structure packing size has changed" warnings when one header
changes the alignment outside of the current file being compiled. I usually
just wrap STL header includes with "#pragma warn -8059" statements to disable
that warning, eg:

#pragma warn -8059
#include <list>
#pragma warn .8059


I have never had any problem with the STL using its own alignment, though.

Here is someone else's analysis of the issue (at least back in the BCB4 days,
but it also applied to some later versions, maybe it still applies today?):

http://www.decompile.com/cpp/faq/w8059_structure_packing_size.htm

--
Remy Lebeau (TeamB)
Dan Ambrose

Posts: 87
Registered: 12/11/03
Re: data alignment problem std::list forces BYTE aligment [Edit]
Click to report abuse...   Click to reply to this thread Reply
  Posted: Dec 20, 2014 1:32 PM   in response to: Remy Lebeau (Te... in response to: Remy Lebeau (Te...
Remy Lebeau (TeamB) wrote:
Dan wrote:

I discovered that

#include <list>

Forces the alignment to BYTE.

The STL as a whole forces its own alignment (via "#pragma option push -a")
and restores the original alignment when done (via "#pragma option pop"),
and has done so for many years. In earlier versions, the two pragmas were
in different header files (_prolog.h and _epilog.h) so the compiler would
issue "W8059 Structure packing size has changed" warnings when one header
changes the alignment outside of the current file being compiled. I usually
just wrap STL header includes with "#pragma warn -8059" statements to disable
that warning, eg:

#pragma warn -8059
#include <list>
#pragma warn .8059


I have never had any problem with the STL using its own alignment, though.

Here is someone else's analysis of the issue (at least back in the BCB4 days,
but it also applied to some later versions, maybe it still applies today?):

http://www.decompile.com/cpp/faq/w8059_structure_packing_size.htm

--
Remy Lebeau (TeamB)

Remy,

If everything was working right then I would have never discovered the problem.

Ok lets analyze this.

#include <list> Seems to change the alignment to BYTE and doesn't put it back.

I have a test program with two units. The first has a main form and some test buttons.
The 2nd unit doesn't have much in it just a dummy widget class.

The main form includes but doesn't use <list>
This causes it to use byte alignment of Widget.

The 2nd test unit module has Widget. It returns sizeof(Widget) as 4 bytes larger than the main form. It does this because the default compiler alignment is quad word.
But the main unit and form, since it includes <list> it disturbs the alignment. Widget doesn't use <list>.

At the point you #include <list> it seems like it FORCES THE ALLIGMENT to byte and doesn't put it back.
Shouldn't the compiler keep track of all the precompiled structures and only use byte on something that inherits, is or references a <list> object ?

In other words, the point and order that you include <list> makes all the difference.

Here is another pitfall. Setting the compiler alignment to BYTE doesn't fix the problem. The entire VCL and many of the other libraries are aligned on other boundaries for efficiency.
So that those api's work BYTE alignment is being automatically changed by the compiler right ?

Maybe I'm missing something. But this looks like a bug somewhere.

Or maybe there is some rule that if you are going to include <list> it needs to be before or after the VCL.

Maybe I should post an example?

How do you upload code example here. I've never done that before.

BTW I found two other unrated compiler bugs. I have an improperly defined derived container class with a bug that makes the compiler fall apart. You get now error. The editor suddenly says read only for the currently opened file. Only way out is to close the project and re-open. I need to post that in case its not fixed already.
Dan

Remy Lebeau (Te...


Posts: 9,447
Registered: 12/23/01
Re: data alignment problem std::list forces BYTE aligment [Edit]
Click to report abuse...   Click to reply to this thread Reply
  Posted: Dec 21, 2014 10:08 PM   in response to: Dan Ambrose in response to: Dan Ambrose
Dan wrote:

#include <list> Seems to change the alignment to BYTE and doesn't
put it back.

Yes, it does. There is a "#pragma option push" at the top of the file, and
a "#pragma option pop" at the bottom. You can use "#pragma alignment" to
verify that the original alignment is being restored:

#pragma alignment
#include <list>
#pragma alignment


The main form includes but doesn't use <list> This causes it to use
byte alignment of Widget.

I am not able to reproduce what you describe. Confirmed with sizeof(), offsetof(),
and __alignof(). "#include <list>" does not change the alignment of the
code that uses it.

Maybe I should post an example?

Yes please.

How do you upload code example here. I've never done that before.

You can attach files to posts in the attachments forum. Or just simplify
the example to its bare minimum to reproduce the problem, and then copy-paste
the code into a post here.

--
Remy Lebeau (TeamB)
Dan Ambrose

Posts: 87
Registered: 12/11/03
Re: data alignment problem std::list forces BYTE aligment
Click to report abuse...   Click to reply to this thread Reply
  Posted: Dec 21, 2014 8:31 AM   in response to: Dan Ambrose in response to: Dan Ambrose
Dan Ambrose wrote:
I'm using C++ Builder XE5

#include <list>

Changes the data alignment. std::list forces BYTE alignment
This causes problems.

I've been investigating this problem for several days. It all started when I enabled codeguard. You get a GPF in constructor saying the size was 4 bytes too small.
First thing I did was checked the data alignment.
Project | Options | Compiler | Data Alignment
It was at the default Quad Word.
I changed it to byte for all platforms. Rebuilt and test. No change.

Before I found the problem I made a unit that gets included and used by other modules. In that unit I put a static function Widget::getsize to return sizeof(Widget);
In other modules I directly call sizeof(Widget) and compare it to the static function Widget::getsize
Sometimes they match. When they don't the static function is always 4 bytes smaller.

You google and get back a punch of hits saying to change the 'Zero length empty base class'. I tried changing both of them. No difference.

So I pasted a list every included header file from all the other modules in my test unit. Then systematically tested each one within
the test unit itself. To find out what was changing the alignment.
I discovered that
#include <list>
Forces the alignment to BYTE.

It doesn't matter what you set Project | Options | Compiler | Data Alignment
It gets ignored.

So that has brought me here asking for help.

Is there some known rule about <list> that changes alignment to byte ?

Is there some rule about the order of include when using the VCL ?

Could this be some bug in the dinkumware header file ?

Is this discussed anywhere in the embarcadero documentation ?

Books - I have "The C++ Standard Library" by Nicolai Josuttis
I bought that in 1999 and read it back then when I was developing a project.
Its been 14 years since I read it. If there is anything in there that I forgot please do tell me about it.

Edited by: Dan Ambrose on Dec 20, 2014 8:45 AM

Ok I think I found the problem. I made more test programs and the problem went away. So I compared project options.
Under ... Project Options | Additional options to pass the compiler

-tWM -wdef -wstl -wamp -wuse -Q -6 -wcln -Vx -a1 -wnod -wamb -wstu -wasm -r- -xp -k -Ve

All of the above are entered in the versions that don't work

On a test program that is just a blank form ( NOTHING ELSE. ) Additional options is empty.

So when I remove ALL 18 of the above "options to pass the compiler " The alignment problems goes away.

I never put any a single one of those in there my self. None of them. It wasn't me. Must have been Frank Borland LOL But seriously ... Some other option or something else automatically put those in there at some point. Enabling Code guard or something did all of that. Does anybody recognize all of those options or have any idea what puts those in ?

Any clues or tips would be appreciated.
Dan - St Louis MO

Legend
Helpful Answer (5 pts)
Correct Answer (10 pts)

Server Response from: ETNAJIVE02