C++ treats the members of an unnamed, untagged local union as
variables of
the scope which encloses the union, as below:
int main()
{
union
{
int a;
char c;
};
a = 20;
c = 'a';
}
Similar structs are not possible, that is, replacing the union
keyword with struct does not compile. Why? Also, why not extend the
same thing for unnamed, untagged unions to work for global scope as
well? Why should we make them static explicitly?
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
0
|
|
|
|
Reply
|
glongword
|
5/1/2004 12:26:52 PM |
|
In message <7e3a6f40.0404301310.44a3c570@posting.google.com>, glongword
<glongword@yahoo.com> writes
>C++ treats the members of an unnamed, untagged local union as
>variables of
>the scope which encloses the union, as below:
>
>int main()
>{
> union
> {
> int a;
> char c;
> };
>
> a = 20;
> c = 'a';
>}
>
> Similar structs are not possible, that is, replacing the union
>keyword with struct does not compile. Why? Also, why not extend the
>same thing for unnamed, untagged unions to work for global scope as
>well? Why should we make them static explicitly?
Actually I think you are asking the wrong questions. The question, IMO,
should be 'why do we allow unnamed unions at class scope to have these
special privileges? Should they not be treated the same as all other
local UDTs?
--
Francis Glassborow ACCU
Author of 'You Can Do It!' see http://www.spellen.org/youcandoit
For project ideas and contributions: http://www.spellen.org/youcandoit/projects
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
0
|
|
|
|
Reply
|
Francis
|
5/2/2004 1:43:29 AM
|
|
glongword@yahoo.com (glongword) writes:
> C++ treats the members of an unnamed, untagged local union as
> variables of
> the scope which encloses the union, as below:
>
> int main()
> {
> union
> {
> int a;
> char c;
> };
>
> a = 20;
> c = 'a';
> }
>
> Similar structs are not possible, that is, replacing the union
> keyword with struct does not compile.
I don't have an answer to your question, but, I do have a related
question of my own:
Microsoft supports unamed structs as an extension. And g++ supports
unamed structs as an extension if the flag -fms-extensions is
passed. Now, I have two questions about this (common?) extension:
(a) What does it mean?
(b) Is there any good reason to use it, besides 'because it is in
the microsoft headers'?
Put another way, can someone present an example of where:
struct foo
{
struct
{
int a;
int b;
};
};
is superior to:
struct foo
{
int a;
int b;
};
and explain why?
> Why? Also, why not extend the
> same thing for unnamed, untagged unions to work for global scope as
> well?
What would be the semantics of an 'utagged union at global scope'?
What would you use such a feature for?
> Why should we make them static explicitly?
This question I don't understand at all.
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
0
|
|
|
|
Reply
|
llewelly
|
5/2/2004 10:43:52 AM
|
|
Francis Glassborow <francis@robinton.demon.co.uk> wrote in message news:<jJTHsnWzG6kAFw+6@robinton.demon.co.uk>...
> Actually I think you are asking the wrong questions. The question, IMO,
> should be 'why do we allow unnamed unions at class scope to have these
> special privileges? Should they not be treated the same as all other
> local UDTs?
Yeah, that's another way of putting it. The behavior with unions
seemed somewhat intuitive to me and my first reaction was, why not
extend it to structures? The work to be done by the compiler to
facilitate this seems to be the same for both structs and unions.
Unions may be a little easier to handle as the storage is shared by
the members, but that is too simple to be the actual reason. Any
hints?
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
0
|
|
|
|
Reply
|
glongword
|
5/2/2004 11:08:26 AM
|
|
llewelly <llewelly.at@xmission.dot.com> wrote in message news:<86wu3wkymp.fsf@Zorthluthik.local.bar>...
> What would be the semantics of an 'utagged union at global scope'?
> What would you use such a feature for?
The members of a global unnamed untagged union would be
accessible to the whole file ( an extension to the earlier property of
being open to the scope in which the union was defined). One would
expect them (at least, I did) to have all the properties of global
variables, like being available across all the translation units
(continued below).
I could use the feature the same way I use it at other scopes. It
just seems intuitive to extend the feature.
>
> > Why should we make them static explicitly?
>
> This question I don't understand at all.
Like I said, when defined at global scope they do not exactly
behave like global variables. The compiler gives an error stating we
need to make the union static. The effect is that the members are now
file static.
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
0
|
|
|
|
Reply
|
glongword
|
5/3/2004 9:33:38 AM
|
|
In message <7e3a6f40.0405012302.7d89e2ea@posting.google.com>, glongword
<glongword@yahoo.com> writes
> Yeah, that's another way of putting it. The behavior with unions
>seemed somewhat intuitive to me and my first reaction was, why not
>extend it to structures? The work to be done by the compiler to
>facilitate this seems to be the same for both structs and unions.
>Unions may be a little easier to handle as the storage is shared by
>the members, but that is too simple to be the actual reason. Any
>hints?
The point at issue was that if two variables at class scope were to
share storage, how should that be expressed? Allowing the same semantics
for unnamed structs/classes buys us nothing other than syntactic
consistency.
struct ms{
union {
int i;
char c[sizeof int];
};
struct{
double d;
unsigned int ui;
};
};
Now the union above says something that is difficult to say any other
way (well we could handle a block of raw memory and cast pointers of
suitable types to it but that is overly complex) The struct adds no
value we might just as well have placed d and ui directly in the scope
of ms. Understanding why we have anonymous unions at class scope also
tells us why there is no benefit from extending the concept.
--
Francis Glassborow ACCU
Author of 'You Can Do It!' see http://www.spellen.org/youcandoit
For project ideas and contributions: http://www.spellen.org/youcandoit/projects
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
0
|
|
|
|
Reply
|
Francis
|
5/3/2004 3:24:26 PM
|
|
llewelly <llewelly.at@xmission.dot.com> wrote in message news:<86wu3wkymp.fsf@Zorthluthik.local.bar>...
> Put another way, can someone present an example of where [anonymous struct member] is superior to [moving inner members to the outer class].
Here are a couple of things you can do with the anonymous struct. I'd
hesitate to hype these capabilities as superior.
struct foo
{
int a;
struct
{
int b;
double c;
};
int d;
};
struct bar
{
int x;
double y;
};
foo u = { 1, { 2 }, 3 }; // different meaning without anon struct
bar v;
// Padding issues mess this up without anon struct
memcpy(&v, &foo.b, sizeof(bar));
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
0
|
|
|
|
Reply
|
wade
|
5/4/2004 10:32:46 AM
|
|
glongword@yahoo.com (glongword) wrote in message news:<7e3a6f40.0404301310.44a3c570@posting.google.com>...
> C++ treats the members of an unnamed, untagged local union as
> variables of
> the scope which encloses the union, as below:
>
> int main()
> {
> union
> {
> int a;
> char c;
> };
>
> a = 20;
> c = 'a';
> }
>
> Similar structs are not possible, that is, replacing the union
> keyword with struct does not compile. Why? Also, why not extend the
> same thing for unnamed, untagged unions to work for global scope as
> well? Why should we make them static explicitly?
>
Unions are all about saving memory by sharing the same memory
locations between the members. A struct on the otherhand does not
have the same effect on memory layout. So, the question is, what
would the difference be between an anonymous, untagged struct and just
declaring the variables (on the stack or in global memory)? There
isn't any difference that I can see, so why have the extra syntax?
Personally, I think that the anonymous, untagged union syntax would
offer surprises to the unsuspecting maintenance programmer down the
road. That would be my guess as to why you have to explicitly declare
the union as static if it is in global scope. Personally, I would
hope the IDE would be sounding Klaxons. :) I can just see the poor
maintenance programmer saying "How can using this floating point
variable here all of the sudden start making the robot walk backwards?
That's controlled by this other variable!" Or some such thing.
joe
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
0
|
|
|
|
Reply
|
jgreer
|
5/4/2004 10:33:15 AM
|
|
In message <2bbfa355.0405030521.5598fdb9@posting.google.com>, Bill Wade
<wade@stoner.com> writes
>llewelly <llewelly.at@xmission.dot.com> wrote in message news:<86wu3wkymp.fsf@Zorthluthik.local.bar>...
> > Put another way, can someone present an example of where [anonymous struct member] is superior to [moving inner members to the outer class].
>
>Here are a couple of things you can do with the anonymous struct. I'd
>hesitate to hype these capabilities as superior.
>
>struct foo
>{
> int a;
> struct
> {
> int b;
> double c;
> };
> int d;
>};
>
>struct bar
>{
> int x;
> double y;
>};
>
>foo u = { 1, { 2 }, 3 }; // different meaning without anon struct
>bar v;
>
>// Padding issues mess this up without anon struct
>memcpy(&v, &foo.b, sizeof(bar));
And if that were all it allowed (deep traps for the unwary) I would not
even want to consider it. However there is a special case:
struct foo {
int a;
struct {
int b:1;
int c:2;
};
};
which in C++ allows us the convenience of packaging up a number of
bit-fields. However note that even there:
struct bar {
int a;
int b:1;
int b:2;
};
is OK.
--
Francis Glassborow ACCU
Author of 'You Can Do It!' see http://www.spellen.org/youcandoit
For project ideas and contributions: http://www.spellen.org/youcandoit/projects
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
0
|
|
|
|
Reply
|
Francis
|
5/4/2004 8:50:31 PM
|
|
wade@stoner.com (Bill Wade) writes:
> llewelly <llewelly.at@xmission.dot.com> wrote in message news:<86wu3wkymp.fsf@Zorthluthik.local.bar>...
> > Put another way, can someone present an example of where [anonymous struct member] is superior to [moving inner members to the outer class].
>
> Here are a couple of things you can do with the anonymous struct. I'd
> hesitate to hype these capabilities as superior.
>
> struct foo
> {
> int a;
> struct
> {
> int b;
> double c;
> };
> int d;
> };
>
> struct bar
> {
> int x;
> double y;
> };
>
> foo u = { 1, { 2 }, 3 }; // different meaning without anon struct
> bar v;
>
> // Padding issues mess this up without anon struct
> memcpy(&v, &foo.b, sizeof(bar));
I don't find either of these examples convincing (though I did find
another example elsewhere in this thread which I did find
potentially useful.) The first is just different, not really
better or worse, and the second seems symptomatic of flawed
thinking; why is memcpy better than assignment, and what guarantee
do you have that foo::struct and bar will remain layout
compatible?
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
0
|
|
|
|
Reply
|
llewelly
|
5/4/2004 8:51:36 PM
|
|
llewelly <llewelly.at@xmission.dot.com> wrote in message news:<86y8o8uqv2.fsf@Zorthluthik.local.bar>...
> wade@stoner.com (Bill Wade) writes:
> > // Padding issues mess this up without anon struct
> > memcpy(&v, &foo.b, sizeof(bar));
>
> why is memcpy better than assignment, and what guarantee
> do you have that foo::struct and bar will remain layout
> compatible?
Examples necessarily leave out detail. I use memcpy instead of
assignment when one of the following is true.
1) I want to copy bytes without modification.
2) Source and/or destination may not be properly aligned.
3) The data may contain a trap representation, and I don't want to get
trapped.
4) On a particular platform, memcpy may be faster than assignment.
These events are (other than (4)) are most likely to occur when I'm
talking to something other than the C++ code in my process (ie I'm
talking to a piece of hardware, or a file, or a network protocol, or
another language).
In all of these cases it is difficult to guarantee that foo::struct
and bar remain consistent. In other words the source definition of
bar is not really in C++, it is somewhere else. However alignment
might be the least of my worries. I've also got to be sure that I
understand the byte-representation of int and double, both in my
process, and at the external location and that I can actually transmit
and receive arbitrary binary data (what if my bytes are 8-bit, and his
are 9-bit?).
Most likely the closest thing to a guarantee is provided by #if (or a
similar mechanism at run time or link time or install time)
surrounding the code in the example:
#if I_AM_RUNNING_ON_FRIZZLE_VERSION_7
#if BAR_IS_FROM_FRAZZLE_VERSION_3
... code in the example ...
#endif
#endif
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
0
|
|
|
|
Reply
|
wade
|
5/7/2004 11:58:42 AM
|
|
jgreer@nsisoftware.com (Joe Greer) wrote
> Personally, I would
> hope the IDE would be sounding Klaxons. :) I can just see the poor
> maintenance programmer saying "How can using this floating point
> variable here all of the sudden start making the robot walk backwards?
> That's controlled by this other variable!" Or some such thing.
I realize that "undefined behavior" means that no matter what happens,
we can't blame the compiler maker.
But if my accounting program suddenly materializes a robot walking
backwards, I'm going to call the National Enquirer!
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
0
|
|
|
|
Reply
|
allan_w
|
5/7/2004 1:06:12 PM
|
|
> "Joe Greer" <jgreer@nsisoftware.com> wrote
>
> Unions are all about saving memory by sharing the same memory
> locations between the members. A struct on the otherhand does not
> have the same effect on memory layout. So, the question is, what
> would the difference be between an anonymous, untagged struct and just
> declaring the variables (on the stack or in global memory)? There
> isn't any difference that I can see, so why have the extra syntax?
Occasionally, you have a need to force global objects to be consecutive in
memory. That's what an anonymous structure does. This wouldn't come up in
"normal" programming, but I've encountered situations in system programming
where it is useful.
--
Ciao, Paul D. DeRocco
Paul mailto:pderocco@ix.netcom.com
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
0
|
|
|
|
Reply
|
Paul
|
5/8/2004 9:38:10 AM
|
|
allan_w@my-dejanews.com (Allan W) writes:
> jgreer@nsisoftware.com (Joe Greer) wrote
>> Personally, I would
>> hope the IDE would be sounding Klaxons. :) I can just see the poor
>> maintenance programmer saying "How can using this floating point
>> variable here all of the sudden start making the robot walk backwards?
>> That's controlled by this other variable!" Or some such thing.
>
> I realize that "undefined behavior" means that no matter what happens,
> we can't blame the compiler maker.
No! It means handling the situation is entirely QoI . It's true there
are many such situations which are difficult for implementators
to handle reasonably, but there are others where many
implementators can and should provide some run-time or
compile-time error.
>
> But if my accounting program suddenly materializes a robot walking
> backwards, I'm going to call the National Enquirer!
Somebody in the business of selling backwards walking robots might
want an implementation to provide that feature. :-)
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
0
|
|
|
|
Reply
|
llewelly
|
5/9/2004 2:10:31 AM
|
|
Bill Wade <wade@stoner.com> schrieb in im Newsbeitrag:
2bbfa355.0405030521.5598fdb9@posting.google.com...
> llewelly <llewelly.at@xmission.dot.com> wrote in message
news:<86wu3wkymp.fsf@Zorthluthik.local.bar>...
> > Put another way, can someone present an example of where [anonymous
struct member] is superior to [moving inner members to the outer class].
>
> Here are a couple of things you can do with the anonymous struct. I'd
> hesitate to hype these capabilities as superior.
>
> struct foo
> {
> int a;
> struct
> {
> int b;
> double c;
> };
> int d;
> };
>
> struct bar
> {
> int x;
> double y;
> };
>
> foo u = { 1, { 2 }, 3 }; // different meaning without anon struct
> bar v;
What is the difference in meaning with and without an anonymous struct?
>
> // Padding issues mess this up without anon struct
> memcpy(&v, &foo.b, sizeof(bar));
I can't figure out how anonymous structs can possibly affect alignment,
please explain.
Best regards,
Matthias Hofmann
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
0
|
|
|
|
Reply
|
Matthias
|
5/9/2004 12:40:14 PM
|
|
"Paul D. DeRocco" <pderocco@ix.netcom.com> wrote in message news:<ilGmc.10833$Hs1.9190@newsread2.news.pas.earthlink.net>...
> Occasionally, you have a need to force global objects to be consecutive in
> memory. That's what an anonymous structure does. This wouldn't come up in
> "normal" programming, but I've encountered situations in system programming
> where it is useful.
Doesn't defining variables consecutively achieve the same thing?
It might not, if some are private and some are public, but there is no
point in declaring members of an anonymous struct anything other than
public. Is the language not supposed to guarantee that? The use I had
in mind was to logically group the variables. Anonymous struct would
say they are related in some way.
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
0
|
|
|
|
Reply
|
glongword
|
5/9/2004 1:43:20 PM
|
|
In message <7e3a6f40.0405080601.31737e62@posting.google.com>, glongword
<glongword@yahoo.com> writes
>"Paul D. DeRocco" <pderocco@ix.netcom.com> wrote in message news:<ilGmc.10833$Hs1.9190@newsread2.news.pas.earthlink.net>...
>
> > Occasionally, you have a need to force global objects to be consecutive in
> > memory. That's what an anonymous structure does. This wouldn't come up in
> > "normal" programming, but I've encountered situations in system programming
> > where it is useful.
>
> Doesn't defining variables consecutively achieve the same thing?
>It might not, if some are private and some are public, but there is no
>point in declaring members of an anonymous struct anything other than
>public. Is the language not supposed to guarantee that? The use I had
>in mind was to logically group the variables. Anonymous struct would
>say they are related in some way.
His original point is well taken. Given:
int i;
int array[1000];
there is no requirement that i should, in effect have an address of
(array-1). There certainly have been compilers that placed arrays into
different memory form non-arrays. However
struct x{
int i;
int array[1000];
};
could, in theory, have padding between i and array but the language
requires that they be in the same memory pool and that any padding
between them be part of the x objects.
--
Francis Glassborow ACCU
Author of 'You Can Do It!' see http://www.spellen.org/youcandoit
For project ideas and contributions: http://www.spellen.org/youcandoit/projects
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
0
|
|
|
|
Reply
|
Francis
|
5/9/2004 11:18:49 PM
|
|
"Paul D. DeRocco" <pderocco@ix.netcom.com> wrote in message news:<ilGmc.10833$Hs1.9190@newsread2.news.pas.earthlink.net>...
>
> Occasionally, you have a need to force global objects to be consecutive in
> memory. That's what an anonymous structure does. This wouldn't come up in
> "normal" programming, but I've encountered situations in system programming
> where it is useful.
That's a good point. I have yet to see a compiler that doesn't layout
variables consecutively, but I can see that there might be a need for
alternate layouts. It has also come to my attention via reading other
threads that bitfields fall into the anonymous struct category as
well. I can't say that I am yet convinced that having either one of
them be anonymous is such a great idea. I suppose it's because I work
on large systems where it would be easy to forget that a variable was
part of a union or a bitfield. However, I can see where someone may
want to do that for low level programming.
joe
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
0
|
|
|
|
Reply
|
jgreer
|
5/10/2004 9:25:58 PM
|
|
"Matthias Hofmann" <hofmann@anvil-soft.com> wrote in message news:<c7khuc$svb$1@news1.nefonline.de>...
> Bill Wade <wade@stoner.com> schrieb in im Newsbeitrag:
> > struct foo
> > {
> > int a;
> > struct
> > {
> > int b;
> > double c;
> > };
> int d;
> > };
> >
> > struct bar
> > {
> > int x;
> > double y;
> > };
> >
> > foo u = { 1, { 2 }, 3 }; // different meaning without anon struct
> > bar v;
>
> What is the difference in meaning with and without an anonymous struct?
With anon struct the meaning is { 1, 2, 0, 3 }
without the meaning is { 1, 2, 3, 0 }
> > // Padding issues mess this up without anon struct
> > memcpy(&v, &foo.b, sizeof(bar));
>
> I can't figure out how anonymous structs can possibly affect alignment,
> please explain.
Suppose sizeof(T) == alignmentof(T), sizeof(int)==4,
sizeof(double)==8.
For a POD struct, the data members are positioned in order of their
declaration. Also the first member of a POD struct is at the same
address as the struct.
With the anon struct, there must be padding between a and b (so that
the anon struct is properly aligned) and between b and c (so that c is
properly aligned)). Without the anon struct, no such padding would be
required.
In either case there would have to be padding somewhere after c
(alignment for the foo and c are both at least eight, but foo has only
four non-padding bytes after c).
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
0
|
|
|
|
Reply
|
wade
|
5/12/2004 6:09:24 PM
|
|
|
18 Replies
282 Views
(page loaded in 0.126 seconds)
|