What's the use of anonymous structs?

R

Richard Heathfield

Fred Phillips said:
Title says ["What's the use of anonymous structs?"]

As far as I can discern, C doesn't provide such a feature. So the answer is
"none, as far as C is concerned". If your implementation provides such a
feature as an extension, consult its documentation to find out why.

As a rule, "What's the use of..." questions are pretty pointless. If you
can't think of a use for something, don't use it.
 
R

robertwessel2

Title says it all...

In the future, please include your question in the body of the post.
What's the use of anonymous structs?


There are (fairly rare) occasions where you want to include a group of
fields, but care little about the grouping provided by the structure,
and, for whatever reason, you find that the extra level of reference
is burdensome or doesn't contribute to clarity. So you can do
something like:

struct date {int year; int month; int day;};
struct foo {int a; struct date; int b;};

int func(struct foo *s)
{
return s->month; /* note lack of intermediate qualification */
}

This is somewhat more common with a union, where you have several
items whose storage you want to overlap, but other than that they're
not really members of a group, and the union name is just clutter.
For example:

struct bar {int a; union {int aa; double bb; long cc;}; int c;};

Which then allows:

struct bar sb;
....
sb.bb = 1.0;


As I said, fairly rare.
 
F

Fred Phillips

Fred Phillips said:
Title says ["What's the use of anonymous structs?"]

As far as I can discern, C doesn't provide such a feature. So the
answer is "none, as far as C is concerned". If your implementation
provides such a feature as an extension, consult its documentation to
find out why.

As a rule, "What's the use of..." questions are pretty pointless. If
you can't think of a use for something, don't use it.

Sorry, I guess I wasn't clear. I mean things like
struct { int a; int b; } c;
which is certainly valid C. However, this anonymous struct doesn't seem
to be compatible with any other anonymous struct of the same signature.

For example, consider the following code:

struct { int a; int b; } foo()
{
struct { int a; int b; } c;
c.a=5;
c.b=8;
return c; /* BOOM */
}

main()
{
struct { int a; int b; } c;
c=foo(); /* BANG */
printf("%d %d\n", c.a, c.b);
}

This won't compile - gives an error about incompatible return types at
line BOOM, and incompatible assignment types at line BANG.

So what's the point of allowing anonymous structs if they can't be
passed around in functions or assigned between each other?
 
K

Keith Thompson

Richard Heathfield said:
Fred Phillips said:
Title says ["What's the use of anonymous structs?"]

As far as I can discern, C doesn't provide such a feature. So the answer is
"none, as far as C is concerned". If your implementation provides such a
feature as an extension, consult its documentation to find out why.

Maybe. It depends on what the OP is really asking about.

You can declare something like this:

struct {
int x;
int y;
} obj;

The struct object "obj" is clearly not anonymous (its name is "obj"),
but the struct type has no name.

The advantage of this, I suppose, is that if you're only going to have
one object of the type, a name for the type would be superfluous. It
might be a decent way to provide a logical grouping for a set of
objects (almost like a C++ namespace, but far more restrictive).

But if C required all struct types to have a tag ("struct foo { ... }"),
it wouldn't have caused any real problems. In the few cases where the
tag name is irrelevant, you could just make up something arbitrary.
As a rule, "What's the use of..." questions are pretty pointless. If you
can't think of a use for something, don't use it.

It depends. If I'm learning a new language, and I run across a
feature for which I can't think of a use, learning how it's actually
used can be very instructive.
 
E

Eric Sosman

Fred said:
Fred Phillips said:
Title says ["What's the use of anonymous structs?"]
As far as I can discern, C doesn't provide such a feature. So the
answer is "none, as far as C is concerned". If your implementation
provides such a feature as an extension, consult its documentation to
find out why.

As a rule, "What's the use of..." questions are pretty pointless. If
you can't think of a use for something, don't use it.

Sorry, I guess I wasn't clear. I mean things like
struct { int a; int b; } c;
which is certainly valid C. However, this anonymous struct doesn't seem
to be compatible with any other anonymous struct of the same signature.
[...]

It's compatible with an identically-declared struct in
a different module ("translation unit") but not with such
a struct in the same module. (Thus, we can have two struct
variables in one module that are incompatible with each
other, but are each compatible with a third struct in a
different module -- strange, but true.)

What good are they? Sometimes they're useful as single-
instance global variables, particularly in small programs.

void func1(int, double);
void func2(int, double);
void func3(int, double);

static struct {
char *name;
void (*func)(int, double);
} funcsToTest[] = {
{ "func1", func1 },
{ "func2", func2 },
{ "blue funk", func3 },
};

.... is a construct I've used in connection with timing tests
of alternative implementations of something or other. The
program doesn't need to create additional instances, or even
to point at them: It just plucks information from this little
table of goodies and uses it.
 
Y

ymuntyan

Fred said:
Fred Phillips said:
Title says ["What's the use of anonymous structs?"]
As far as I can discern, C doesn't provide such a feature. So the
answer is "none, as far as C is concerned". If your implementation
provides such a feature as an extension, consult its documentation to
find out why.
As a rule, "What's the use of..." questions are pretty pointless. If
you can't think of a use for something, don't use it.
Sorry, I guess I wasn't clear. I mean things like
struct { int a; int b; } c;
which is certainly valid C. However, this anonymous struct doesn't seem
to be compatible with any other anonymous struct of the same signature.
[...]

It's compatible with an identically-declared struct in
a different module ...

Doesn't this contradict 6.7.2.3p4?

Best regards,
Yevgen
 
R

Richard Heathfield

Fred Phillips said:
Fred Phillips said:
Title says ["What's the use of anonymous structs?"]

As far as I can discern, C doesn't provide such a feature. So the
answer is "none, as far as C is concerned". If your implementation
provides such a feature as an extension, consult its documentation to
find out why.

As a rule, "What's the use of..." questions are pretty pointless. If
you can't think of a use for something, don't use it.

Sorry, I guess I wasn't clear. I mean things like
struct { int a; int b; } c;

Oh, I see. Yes, that's legal all right. But my answer remains as it was
before:

So what's the point of allowing anonymous structs if they can't be
passed around in functions or assigned between each other?

Well, you can use 'em in typedefs:

typedef struct { int a; int b; } typename;

Now you can instantiate them via the synonym, and a tag would indeed be
pretty pointless. But frankly, I prefer to separate the typedef from the
struct definition, which of course brings us right back to the tag.
 
Y

ymuntyan

Fred said:
Fred Phillips said:
Title says ["What's the use of anonymous structs?"]
As far as I can discern, C doesn't provide such a feature. So the
answer is "none, as far as C is concerned". If your implementation
provides such a feature as an extension, consult its documentation to
find out why.
As a rule, "What's the use of..." questions are pretty pointless. If
you can't think of a use for something, don't use it.
Sorry, I guess I wasn't clear. I mean things like
struct { int a; int b; } c;
which is certainly valid C. However, this anonymous struct doesn't seem
to be compatible with any other anonymous struct of the same signature.
[...]

It's compatible with an identically-declared struct in
a different module ("translation unit")

Doesn't it contradict 6.7.2.3p4: "Each declaration of a structure,
union, or enumerated
type which does not include a tag declares a distinct type"?

Regards,
Yevgen
 
S

sureshkumar.manimuthu

Title says it all...

One common usage is structure inside structure/union.

struct rect
{
struct { int x; int y } start;
struct { int x; int y } end;
};
 
E

Eric Sosman

Fred said:
[...]
Sorry, I guess I wasn't clear. I mean things like
struct { int a; int b; } c;
which is certainly valid C. However, this anonymous struct doesn't seem
to be compatible with any other anonymous struct of the same signature.
[...]
It's compatible with an identically-declared struct in
a different module ...

Doesn't this contradict 6.7.2.3p4?

6.7.2.3p4 says the types are distinct, but 6.2.7p1
says they are compatible anyhow.
 
M

Martien Verbruggen

In the future, please include your question in the body of the post.


There are (fairly rare) occasions where you want to include a group of
fields, but care little about the grouping provided by the structure,
and, for whatever reason, you find that the extra level of reference
is burdensome or doesn't contribute to clarity. So you can do
something like:

struct date {int year; int month; int day;};
struct foo {int a; struct date; int b;};

int func(struct foo *s)
{
return s->month; /* note lack of intermediate qualification */
}

Can you provide an example of a compilable program that does this? The
above is certainly refused by gcc (in c89 and c99 mode, as well as in
its default mode)

I agree with gcc on this one, in that I don't believe the above is valid
C. Are you maybe thinking of another language? Which compiler supports
this?
struct bar {int a; union {int aa; double bb; long cc;}; int c;};

Which then allows:

struct bar sb;
...
sb.bb = 1.0;

Ditto for this

Martien
 
T

Thad Smith

Fred said:
Fred Phillips said:
Title says ["What's the use of anonymous structs?"]
Sorry, I guess I wasn't clear. I mean things like
struct { int a; int b; } c;
which is certainly valid C. However, this anonymous struct doesn't seem
to be compatible with any other anonymous struct of the same signature.

I wrote some simulation code recently that had a large module with many
file scope variables containing various states of the simulation. I
wanted to group several of them having to do with a particular aspect,
for example, motor. Rather than defining motorSpeed, motorTorque,
motorTemp, and motorCurrent, I choose to group them as

static struct {
double speed;
double torque;
double temp;
double current;
} motor;

with suitable comments on the individual elements, as well as comment on
the struct itself. The struct naturally shows the association. This
was done for readability.
 
Y

ymuntyan

Fred Phillips wrote:
[...]
Sorry, I guess I wasn't clear. I mean things like
struct { int a; int b; } c;
which is certainly valid C. However, this anonymous struct doesn't seem
to be compatible with any other anonymous struct of the same signature.
[...]
It's compatible with an identically-declared struct in
a different module ...
Doesn't this contradict 6.7.2.3p4?

6.7.2.3p4 says the types are distinct, but 6.2.7p1
says they are compatible anyhow.

Then 6.2.7p1 says they are the same anyhow, yet distinct according to
6.7.2.3p4.
To me it looks like an error, possibility of two anonymous structure
types in
the same translation unit was missed (assuming this, 6.2.7p1 clearly
as an explanation
of why including a header with a structure declaration in two source
files will work).

Best regards,
Yevgen
 
R

Richard

Thad Smith said:
Fred said:
Fred Phillips said:
Title says ["What's the use of anonymous structs?"]
Sorry, I guess I wasn't clear. I mean things like
struct { int a; int b; } c;
which is certainly valid C. However, this anonymous struct doesn't seem
to be compatible with any other anonymous struct of the same signature.

I wrote some simulation code recently that had a large module with
many file scope variables containing various states of the simulation.
I wanted to group several of them having to do with a particular
aspect, for example, motor. Rather than defining motorSpeed,
motorTorque, motorTemp, and motorCurrent, I choose to group them as

static struct {
double speed;
double torque;
double temp;
double current;
} motor;

with suitable comments on the individual elements, as well as comment
on the struct itself. The struct naturally shows the association.
This was done for readability.

This is pretty much exactly what structs are for. I'm not sure I
understand your point here unless it is to explain how to use structs?
 
E

Eric Sosman

Fred Phillips wrote:

[...]
Sorry, I guess I wasn't clear. I mean things like
struct { int a; int b; } c;
which is certainly valid C. However, this anonymous struct doesn't seem
to be compatible with any other anonymous struct of the same signature.
[...]

It's compatible with an identically-declared struct in
a different module ...
Doesn't this contradict 6.7.2.3p4?

6.7.2.3p4 says the types are distinct, but 6.2.7p1
says they are compatible anyhow.


Then 6.2.7p1 says they are the same anyhow, yet distinct according to
6.7.2.3p4.

No, 6.2.7p1 says they are *compatible* types, not that
they are the *same* type.
To me it looks like an error, possibility of two anonymous structure
types in
the same translation unit was missed (assuming this, 6.2.7p1 clearly
as an explanation
of why including a header with a structure declaration in two source
files will work).

I doubt the possibility was "missed." It seems more
likely that making the two tagless types distinct was
purposeful. If the programmer wrote two declarations
rather than just one, he gets two types and not just one.
In particular, the second declaration is not an (illegal)
attempt to re-declare the type of the first one.

Cross-module compatibility addresses a nasty issue
that confronts many separately-compilable languages. If
the compiler processes module A on Tuesday and processes
module B on Wednesday, we can't really talk about a type
compiled in A being "the same" as a type declared in B.
And yet, we want A to create objects of type T and pass
them to B to be processed. Since A and B had separate
declarations for T they can't really have "the same" T,
so the Standard resorts to this notion of "compatibility"
to allow separately-compiled modules to agree on what a
T looks like.
 
B

Ben Pfaff

Martien Verbruggen said:
I agree with gcc on this one, in that I don't believe the above is valid
C. Are you maybe thinking of another language? Which compiler supports
this?

It is a Microsoft extension to C. GCC also supports it, with
-fms-extensions (see last paragraph below):

5.50 Unnamed struct/union fields within structs/unions
======================================================

For compatibility with other compilers, GCC allows you to define a
structure or union that contains, as fields, structures and unions
without names. For example:

struct {
int a;
union {
int b;
float c;
};
int d;
} foo;

In this example, the user would be able to access members of the
unnamed union with code like `foo.b'. Note that only unnamed structs
and unions are allowed, you may not have, for example, an unnamed `int'.

You must never create such structures that cause ambiguous field
definitions. For example, this structure:

struct {
int a;
struct {
int a;
};
} foo;

It is ambiguous which `a' is being referred to with `foo.a'. Such
constructs are not supported and must be avoided. In the future, such
constructs may be detected and treated as compilation errors.

Unless `-fms-extensions' is used, the unnamed field must be a
structure or union definition without a tag (for example, `struct { int
a; };'). If `-fms-extensions' is used, the field may also be a
definition with a tag such as `struct foo { int a; };', a reference to
a previously defined structure or union such as `struct foo;', or a
reference to a `typedef' name for a previously defined structure or
union type.
 
R

robertwessel2

It is a Microsoft extension to C. GCC also supports it, with
-fms-extensions (see last paragraph below):

5.50 Unnamed struct/union fields within structs/unions
======================================================

For compatibility with other compilers, GCC allows you to define a
structure or union that contains, as fields, structures and unions
without names. For example:

struct {
int a;
union {
int b;
float c;
};
int d;
} foo;

In this example, the user would be able to access members of the
unnamed union with code like `foo.b'. Note that only unnamed structs
and unions are allowed, you may not have, for example, an unnamed `int'.

You must never create such structures that cause ambiguous field
definitions. For example, this structure:

struct {
int a;
struct {
int a;
};
} foo;

It is ambiguous which `a' is being referred to with `foo.a'. Such
constructs are not supported and must be avoided. In the future, such
constructs may be detected and treated as compilation errors.

Unless `-fms-extensions' is used, the unnamed field must be a
structure or union definition without a tag (for example, `struct { int
a; };'). If `-fms-extensions' is used, the field may also be a
definition with a tag such as `struct foo { int a; };', a reference to
a previously defined structure or union such as `struct foo;', or a
reference to a `typedef' name for a previously defined structure or
union type.


Anonymous *unions* are standard for C++, and my first mistake was
misremembering that the had (not) been adopted in C99. The second
that it applied to structs too. FWIW, ICC and IBM's C compiler for
AIX supports that as well.
 
Y

ymuntyan

(e-mail address removed) wrote On 10/18/07 09:37,:


(e-mail address removed) wrote:
Fred Phillips wrote:
[...]
Sorry, I guess I wasn't clear. I mean things like
struct { int a; int b; } c;
which is certainly valid C. However, this anonymous struct doesn't seem
to be compatible with any other anonymous struct of the same signature.
[...]
It's compatible with an identically-declared struct in
a different module ...
Doesn't this contradict 6.7.2.3p4?
6.7.2.3p4 says the types are distinct, but 6.2.7p1
says they are compatible anyhow.
Then 6.2.7p1 says they are the same anyhow, yet distinct according to
6.7.2.3p4.

No, 6.2.7p1 says they are *compatible* types, not that
they are the *same* type.

Well, the "compatible" there is italicized, I take it as
that's the definition of "compatible". In other words, it
says something like "Types are compatible if and only if
they are the same". And then it goes to explain what it
means for two types to be "the same".
I doubt the possibility was "missed." It seems more
likely that making the two tagless types distinct was
purposeful. If the programmer wrote two declarations
rather than just one, he gets two types and not just one.
In particular, the second declaration is not an (illegal)
attempt to re-declare the type of the first one.

But it makes stuff like

struct {int a; int b;} a;
struct {int a; int b;} *p = &a;

illegal, or, more realistic,

void callback (void *p)
{
struct {int a; int b;} *data = p;
/* ... */
}

void func (void)
{
struct {int a; int b;} data = {1, 2};
call_something (callback, &data);
}

which doesn't seem to be right (I have a file here with the
following named structures which are used exactly like that,
in two functions each: CheckContextData, ResolveRefData,
RegexResolveData, BufAndIters, the last one is the sexiest).
Wrongness of this plus non-clear wording makes me think
it's an error in the standard.
Cross-module compatibility addresses a nasty issue
that confronts many separately-compilable languages. If
the compiler processes module A on Tuesday and processes
module B on Wednesday, we can't really talk about a type
compiled in A being "the same" as a type declared in B.
And yet, we want A to create objects of type T and pass
them to B to be processed. Since A and B had separate
declarations for T they can't really have "the same" T,
so the Standard resorts to this notion of "compatibility"
to allow separately-compiled modules to agree on what a
T looks like.

Yes. And I believe anonymous structs were just missed here.
Consider this:

// file.h
extern struct {int a; int b;} *a;

It's impossible to actually define that 'a' if you include
the header into the C file; and it's possible all right if
you don't. Weird example of course, and it's why (it's a
hypothesis) this wasn't taken into account - nobody thought
about it or it was too much trouble to add it to the standard
comparing to the benefits.

Best regards,
Yevgen
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,438
Messages
2,571,699
Members
48,796
Latest member
Greg L.
Top