Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > Reading Struct not Located at Four-boundary

Reply
Thread Tools

Reading Struct not Located at Four-boundary

 
 
Öö Tiib
Guest
Posts: n/a
 
      08-22-2010
On 23 aug, 00:03, "Francesco S. Carta" <(E-Mail Removed)> wrote:
> Gennaro Prota <(E-Mail Removed)>, on 22/08/2010 20:56:33, wrote:
>
> >> I have skimmed the standard and I only found a mention about the fact
> >> that a POD type cannot have initial padding, does that suffice to imply
> >> that non-POD types can actually have initial padding or is there some
> >> other explicit reference in the standard?

>
> > I see no explicit reference, but the rules seem to be carefully
> > crafted to allow it. I'm sure someone will come up with an
> > example where it is necessary. I'm just too tired right now to
> > think of anything sensible.

>
> I'm really curious to see an example where such initial padding could
> come useful... anybody else still keeping an eye here?
>


Perhaps it is not about initial padding, but about stuff that may be
before first data member (for example for polymorphism or RTTI). It is
up to implementation so standard is careful not guaranteeing nor
denying that something is there.

 
Reply With Quote
 
 
 
 
Larry Evans
Guest
Posts: n/a
 
      08-22-2010
On 08/21/10 16:16, Francesco S. Carta wrote:
> Larry Evans <(E-Mail Removed)>, on 21/08/2010 14:32:27, wrote:
>
>> On 08/21/10 13:31, Francesco S. Carta wrote:
>> [snip]
>>> I still wonder if the method provided here can be trusted or not:
>>>
>>> http://www.monkeyspeak.com/alignment/

[snip]
>> I'm puzzled by the strideof(T) macro.
>> I would have thought sizeof(Tchar<T>) > size(T) would always be
>> true. OTOH, maybe the compiler knows that T has some padding at
>> the end where it puts the 'char c'.

>
> The author motivates the above macro exactly for that "padding reuse"
> possibility, see the second paragraph:
>
> [quote from http://www.monkeyspeak.com/alignment/ ]

[snip]
> The second case is if T already has some padding in it, and the compiler
> chooses to reuse some of T's padding to store the extra char. In that
> case, Tchar will be the same size as T, and our subtraction will yield
> zero. When that happens, our macro defaults to sizeof(T), which is not
> optimal but is at least known to be a multiple of T's stride. (There is
> some dispute as to whether this case can arise--some believe that it is
> illegal for a compiler to reuse padding like this. Either way, our
> technique deals with it.)
> [/quote]

[snip]
From http://www.open-std.org/jtc1/sc22/wg...cs/dr_074.html,
response g) says such reuse of padding (called sharing of storage
in the ref) is not allowed.

 
Reply With Quote
 
 
 
 
Larry Evans
Guest
Posts: n/a
 
      08-23-2010
On 08/22/10 18:59, Larry Evans wrote:
> On 08/21/10 16:16, Francesco S. Carta wrote:

[snip]
>> [quote from http://www.monkeyspeak.com/alignment/ ]

> [snip]
>> The second case is if T already has some padding in it, and the compiler
>> chooses to reuse some of T's padding to store the extra char. In that
>> case, Tchar will be the same size as T, and our subtraction will yield
>> zero. When that happens, our macro defaults to sizeof(T), which is not
>> optimal but is at least known to be a multiple of T's stride. (There is
>> some dispute as to whether this case can arise--some believe that it is
>> illegal for a compiler to reuse padding like this. Either way, our
>> technique deals with it.)
>> [/quote]

> [snip]
> From http://www.open-std.org/jtc1/sc22/wg...cs/dr_074.html,
> response g) says such reuse of padding (called sharing of storage
> in the ref) is not allowed.
>

I've a feeling of deja vu. This reuse of padding was actually
done to create a tagged union as described in this thread:

http://sourceforge.net/mailarchive/m...ough.gmane.org

In summary, Joel had a utree which was a tagged union; however,
he had to store the tag somewhere which means he had to create
something like:

struct tagged_union
{ u_type u_part;
char tag_part;
};

where u_type was "equivalent" to some union type.
However, that union type had some padding due to
alignment requirements and, to save space, joel
wanted to put the tag_part in that padding.
This was done by store the whole thing a a char
buffer and using template metaprogramming to
extract the u_part and tag_part.

Hope you find it interesting.

-regards,
Larry

 
Reply With Quote
 
James Kanze
Guest
Posts: n/a
 
      08-23-2010
On Aug 22, 10:03 pm, "Francesco S. Carta" <(E-Mail Removed)> wrote:
> Gennaro Prota <(E-Mail Removed)>, on 22/08/2010 20:56:33, wrote:


[...]
> >>> And when T is not a POD, there can be padding before t in


> >> I have skimmed the standard and I only found a mention
> >> about the fact that a POD type cannot have initial padding,
> >> does that suffice to imply that non-POD types can actually
> >> have initial padding or is there some other explicit
> >> reference in the standard?


> > I see no explicit reference, but the rules seem to be
> > carefully crafted to allow it. I'm sure someone will come up
> > with an example where it is necessary. I'm just too tired
> > right now to think of anything sensible.


> I'm really curious to see an example where such initial
> padding could come useful... anybody else still keeping an eye
> here?


It might depend on what you consider "padding". What is certain
is that if C is not a PODS, then there is no guarantee that the
address of a C object is the same as the address of its first
member. In a typical implementation, for example:

struct C
{
int a;
virtual ~C(); // So not PODS
};

C c;

, (void*)&c and (void*)&c.a will not compare equal. (Drop the
virtual destructor, and they are required to by the standard.)

Basically, all the standard is doing is allowing implementations
additional freedom with regards to layout if the type isn't POD.
All of the implementations I know use this freedom in some
specific cases.

--
James Kanze
 
Reply With Quote
 
Francesco S. Carta
Guest
Posts: n/a
 
      08-23-2010
Larry Evans <(E-Mail Removed)>, on 22/08/2010 19:27:08, wrote:

> On 08/22/10 18:59, Larry Evans wrote:


<snip>

>> From http://www.open-std.org/jtc1/sc22/wg...cs/dr_074.html,
>> response g) says such reuse of padding (called sharing of storage
>> in the ref) is not allowed.
>>

> I've a feeling of deja vu. This reuse of padding was actually
> done to create a tagged union as described in this thread:
>
> http://sourceforge.net/mailarchive/m...ough.gmane.org
>
>
> In summary, Joel had a utree which was a tagged union; however,
> he had to store the tag somewhere which means he had to create
> something like:
>
> struct tagged_union
> { u_type u_part;
> char tag_part;
> };
>
> where u_type was "equivalent" to some union type.
> However, that union type had some padding due to
> alignment requirements and, to save space, joel
> wanted to put the tag_part in that padding.
> This was done by store the whole thing a a char
> buffer and using template metaprogramming to
> extract the u_part and tag_part.
>
> Hope you find it interesting.


Indeed, I'm trying to sum up all these references to get a better grasp
on the subject, thanks for them Larry.

--
FSC - http://userscripts.org/scripts/show/59948
http://fscode.altervista.org - http://sardinias.com
 
Reply With Quote
 
Francesco S. Carta
Guest
Posts: n/a
 
      08-23-2010
Öö Tiib <(E-Mail Removed)>, on 22/08/2010 15:24:36, wrote:

> On 23 aug, 00:03, "Francesco S. Carta"<(E-Mail Removed)> wrote:
>> Gennaro Prota<(E-Mail Removed)>, on 22/08/2010 20:56:33, wrote:
>>
>>>> I have skimmed the standard and I only found a mention about the fact
>>>> that a POD type cannot have initial padding, does that suffice to imply
>>>> that non-POD types can actually have initial padding or is there some
>>>> other explicit reference in the standard?

>>
>>> I see no explicit reference, but the rules seem to be carefully
>>> crafted to allow it. I'm sure someone will come up with an
>>> example where it is necessary. I'm just too tired right now to
>>> think of anything sensible.

>>
>> I'm really curious to see an example where such initial padding could
>> come useful... anybody else still keeping an eye here?
>>

>
> Perhaps it is not about initial padding, but about stuff that may be
> before first data member (for example for polymorphism or RTTI). It is
> up to implementation so standard is careful not guaranteeing nor
> denying that something is there.


I understand, thank you for the note Öö.

An explicit mention in the standard would have been nice, though, just
to avoid people wandering around looking for something that is there
just as an implication of something else

--
FSC - http://userscripts.org/scripts/show/59948
http://fscode.altervista.org - http://sardinias.com
 
Reply With Quote
 
Francesco S. Carta
Guest
Posts: n/a
 
      08-23-2010
James Kanze <(E-Mail Removed)>, on 23/08/2010 03:20:27, wrote:

> On Aug 22, 10:03 pm, "Francesco S. Carta"<(E-Mail Removed)> wrote:
>> Gennaro Prota<(E-Mail Removed)>, on 22/08/2010 20:56:33, wrote:

>
> [...]
>>>>> And when T is not a POD, there can be padding before t in

>
>>>> I have skimmed the standard and I only found a mention
>>>> about the fact that a POD type cannot have initial padding,
>>>> does that suffice to imply that non-POD types can actually
>>>> have initial padding or is there some other explicit
>>>> reference in the standard?

>
>>> I see no explicit reference, but the rules seem to be
>>> carefully crafted to allow it. I'm sure someone will come up
>>> with an example where it is necessary. I'm just too tired
>>> right now to think of anything sensible.

>
>> I'm really curious to see an example where such initial
>> padding could come useful... anybody else still keeping an eye
>> here?

>
> It might depend on what you consider "padding". What is certain
> is that if C is not a PODS, then there is no guarantee that the
> address of a C object is the same as the address of its first
> member. In a typical implementation, for example:
>
> struct C
> {
> int a;
> virtual ~C(); // So not PODS
> };
>
> C c;
>
> , (void*)&c and (void*)&c.a will not compare equal. (Drop the
> virtual destructor, and they are required to by the standard.)
>
> Basically, all the standard is doing is allowing implementations
> additional freedom with regards to layout if the type isn't POD.
> All of the implementations I know use this freedom in some
> specific cases.


I see, thanks for the details James.

As I said elsethread, an explicit mention in the standard would have
been nice.

--
FSC - http://userscripts.org/scripts/show/59948
http://fscode.altervista.org - http://sardinias.com
 
Reply With Quote
 
Gennaro Prota
Guest
Posts: n/a
 
      08-24-2010
On 22/08/2010 23.03, Francesco S. Carta wrote:
[...]
>> OK. It had never occurred to me but, apparently, it has been
>> asked, even to the C committee. See bullet g of
>>
>> <http://www.open-std.org/jtc1/sc22/wg14/www/docs/dr_074.html>


[...]

>> BTW, that DR also has some bad news in the answer to bullet a.
>> For the little that I've been able to gather from the new C++0x
>> requirements, this seems an incompatibility between C and C++
>> (because C++ seems to intend that the alignment is a function of
>> the type: an object of the same type has the same alignment. But
>> as you might have seen, I've asked for a confirmation about
>> this, without success. In fact, I'm looking for an effective way
>> to deal with it before C++0x is finalized. Some national body
>> should probably help, as a DR would just be dealt with after the
>> publication of the standard).
>>

>
> Thanks for the references.
>
> As I mentioned elsethread, I'm almost completely unaware of the details
> of the new standard, I only had a read to some articles here and there,
> but sooner or later I'll have to dip my fingers there.


I'm not very up-to-date either. But since I've been playing with
alignment as of lately (due to the experimental fallible<> I
mentioned elsewhere) I had a look at what C++0x has to say about
it, so that I would already code on the ground of what will be
guaranteed (and likely already holds in practice). Alas, the
result was the long message I posted here under the subject

"On alignment (final committee draft for C++0x and n1425 for C1X)"

> Unfortunately I cannot give any help about your reports... isn't there
> in the committee some Italian entity or person that you could contact to
> focus a bit of attention on those issues?


Don't you know that Italy doesn't exist programming-wise? We
were once decent at playing football, but as it concerns
programming and C++ in particular...

> Well maybe you just need to exercise some more patience, your reports
> can still get a feedback before the new publication, I think.
>
> Or eventually, I wonder whether the DR is not the proper shape to
> present those issues, as you say those should be addressed after the
> publication... but I'm far from my firm ground, so I'll be better
> shutting up before writing some (further) silliness


No, the contrary! IMHO the whole paragraph is so broken that
it should be fixed *before* publication. If you look at the core
or library DR lists you'll see that there are at times issues
that remain open for ten years or more. Add that even when the
whole thing is "fixed" it will require compiler vendors to
(monitor the committee decisions and) carefully check if their
implementation respects the resolution. (So: twenty years? Is
that a good guess?)

I had a vague idea to contact someone on the French body
(ahehm... James? Still keeping an eye?) but I'm also
increasingly feeling discouraged. It seems that few people care.
I already wasted a lot of time writing the post (although
noticing the problems took really a nanosecond).

--
Gennaro Prota | I'm available for your projects.
Breeze (preview): <https://sourceforge.net/projects/breeze/>
 
Reply With Quote
 
Gennaro Prota
Guest
Posts: n/a
 
      08-28-2010
On 22/08/2010 20.45, Gennaro Prota wrote:
[...]
>> I'm not understanding why
>> you say the technique would work anyway.

>
> Because both sizeof( Foo ) and sizeof( T ) are multiples of the
> alignment of T. Thus their difference is, too.


I should have been more precise.

It "works" if the requirement is to get the true alignment or a
multiple of it.

In some cases, however (including my usage for the fallible<>
template), this requirement isn't useful.

What I was after was for the buffer in which I'll placement-new
my T to have exactly the same size as T.

Of course I can't just do

union {
unsigned char buffer[ sizeof( T ) ] ;
T dummy ;
} ;

because not all T's can go into a union. So, my idea was to
choose, for each T, a POD type T2 having *the same alignment* as
T (if it exists), and put that in the union. But if the align_of
template begins to "lie" I'm in trouble: it might tell me that
both T and T2 have an alignment of 4 whereas, for instance, T
really aligns at 4 but T2 has a true alignment of 2. Bang, we
are dead. (Note the switch from "I" to "we" )

And what's worse we might be dead at intermittent times (not
necessarily the same moments for "I" and "we").

A scenario where it is still useful, instead, and probably the
one for which the various boost's and then C++0x's facilities
were thought, is when you have a buffer *large enough* and don't
care to waste some of it. In that case, for instance, you may be
able to do some simple math and discard some bytes at the start.

But if I wanted to leave unused space then I'd just resort to
the old trick of using a union ("MaxAlign") with most of the
fundamental types in it. (Which is what I was doing; all this
dance started exactly as an experimental attempt to save
allocation space with respect to using MaxAlign).

So, one thing that I'd be glad to have now is a way to tell if
two types have the same alignment (meant as *minimum*
alignment), without necessarily knowing what the alignment is.
If you know of any technique to do this please voice your voice


Besides that, there's also a completely different approach which
has been wandering though my mind for a while. But I won't make
my ruminations public until I've some feeling that they may
really work.

--
Gennaro Prota | I'm available for your projects.
Breeze (preview): <https://sourceforge.net/projects/breeze/>
 
Reply With Quote
 
Larry Evans
Guest
Posts: n/a
 
      08-28-2010
On 08/28/10 12:48, Gennaro Prota wrote:
[snip]
> But if the align_of
> template begins to "lie" I'm in trouble: it might tell me that
> both T and T2 have an alignment of 4 whereas, for instance, T
> really aligns at 4 but T2 has a true alignment of 2. Bang, we
> are dead. (Note the switch from "I" to "we" )


But if align_of "lies", isn't that a compiler bug?

[snip]
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Can *common* struct-members of 2 different struct-types, that are thesame for the first common members, be accessed via pointer cast to either struct-type? John Reye C Programming 28 05-08-2012 12:24 AM
static struct initialization in a Class:: -- not my struct christian.bongiorno@gmail.com C++ 2 09-20-2006 06:53 PM
Printer not located in new laptop from wireless network =?Utf-8?B?dG1jZ2luNzEwMzk1?= Wireless Networking 3 04-19-2006 02:15 AM
struct my_struct *p = (struct my_struct *)malloc(sizeof(struct my_struct)); Chris Fogelklou C Programming 36 04-20-2004 08:27 AM
To coerce or not...? struct sockaddr vs struct sockaddr_in James Harris C Programming 4 10-09-2003 10:06 PM



Advertisments