Mega Search
23.2 Million


Sign Up

Make a donation  
data alignment problem std::list forces BYTE aligment [Edit]  
News Group: embarcadero.public.cppbuilder.language.cpp

I'm using C++ Builder XE5 

#include 

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 
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    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

Vote for best question.
Score: 0  # Vote:  0
Date Posted: 20-Dec-2014, at 6:45 AM EST
From: Dan Ambrose
 
Re: data alignment problem std::list forces BYTE aligment [E  
News Group: embarcadero.public.cppbuilder.language.cpp
Dan wrote:

> #include   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:

{code}
#pragma alignment
#include 
#pragma alignment
{code}

> The main form includes but doesn't use   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 " 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)

Vote for best answer.
Score: 0  # Vote:  0
Date Posted: 21-Dec-2014, at 10:08 PM EST
From: Remy Lebeau (TeamB)
 
Re: data alignment problem std::list forces BYTE aligment  
News Group: embarcadero.public.cppbuilder.language.cpp
> {quote:title=Dan Ambrose wrote:}{quote}
> I'm using C++ Builder XE5 
> 
> #include 
> 
> 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 
> 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    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

Vote for best answer.
Score: 0  # Vote:  0
Date Posted: 21-Dec-2014, at 8:31 AM EST
From: Dan Ambrose
 
Re: data alignment problem std::list forces BYTE aligment [E  
News Group: embarcadero.public.cppbuilder.language.cpp
> {quote:title=Remy Lebeau (TeamB) wrote:}{quote}
> Dan wrote:
> 
> > I discovered that
> > 
> > #include 
> > 
> > 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:
> 
> {code}
> #pragma warn -8059
> #include 
> #pragma warn .8059
> {code}
> 
> 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   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   
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  it disturbs the alignment.  Widget doesn't use .  

At the point you #include  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  object ?

In other words, the point and order that you include   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  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

Vote for best answer.
Score: 0  # Vote:  0
Date Posted: 20-Dec-2014, at 1:32 PM EST
From: Dan Ambrose
 
Re: data alignment problem std::list forces BYTE aligment [E  
News Group: embarcadero.public.cppbuilder.language.cpp
Dan wrote:

> I discovered that
> 
> #include 
> 
> 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:

{code}
#pragma warn -8059
#include 
#pragma warn .8059
{code}

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)

Vote for best answer.
Score: 0  # Vote:  0
Date Posted: 20-Dec-2014, at 11:30 AM EST
From: Remy Lebeau (TeamB)