typedefs/structs

C

copx

Somehow I totally forgot how typedefs/structs work.
Why doesn't this work:

typedef struct _MY_STRUCT {
int a;
int b;
struct _MY_STRUCT *c;
} MY_STRUCT;

My compiler complains about "incomplete structure MY_STRUCT" etc.
If I try to use MY_STRUCT.

copx
 
M

Mark A. Odell

Somehow I totally forgot how typedefs/structs work.
Why doesn't this work:

typedef struct _MY_STRUCT {

First, names with leading _ are reserved (in general) for the implemtation
so avoid them.
int a;
int b;
struct _MY_STRUCT *c;
} MY_STRUCT;

My compiler complains about "incomplete structure MY_STRUCT" etc.
If I try to use MY_STRUCT.

Second, try it this way:

typedef struct MyStruct MyStruct;

struct MyStruct
{
int a;
int b;
MyStruct *c;
};

Note that a struct tag name and the typedef alias can be the same since
they are in different namespaces.
 
C

copx

Mark A. Odell said:
First, names with leading _ are reserved (in general) for the implemtation
so avoid them.

IIRC names with leading __ are reserved, one _ is perfectly ok IMO.
Second, try it this way:

typedef struct MyStruct MyStruct;

struct MyStruct
{
int a;
int b;
MyStruct *c;
};

Note that a struct tag name and the typedef alias can be the same since
they are in different namespaces.

Well, it works thanks. But I really don't like the fact
that the type and the struct have the same name.
And it breaks if they don't.
It's a matter of taste/style of course but I would still
like to hear about an option to get this working
with differently named struct/type.

copx
 
C

copx

Arthur J. O'Dwyer said:
It really should, modulo UB.

And it does. Sorry, I didn't read
the compiler warning carefully enough.
Somewhere I did something like:

struct MY_STRUCT x;

That 'caused the "incomplete struct" trouble.

copx (ashamed)
 
E

Eric Gorr

copx said:
Somehow I totally forgot how typedefs/structs work.
Why doesn't this work:

typedef struct _MY_STRUCT {
int a;
int b;
struct _MY_STRUCT *c;
} MY_STRUCT;

My compiler complains about "incomplete structure MY_STRUCT" etc.
If I try to use MY_STRUCT.

Personally, I prefer doing such things by writing:

typedef struct
{
...
} MY_STRUCT;
 
G

Goran Larsson

IIRC names with leading __ are reserved, one _ is perfectly ok IMO.

No, it is not ok.

From ANSI/ISO/IEC 9899-1999:

| 7.1.3 Reserved identifiers
| . . .
|
| - All identifiers that begin with an underscore and either an uppercase
| letter or another underscore are always reserved for any use.
|
| - All identifiers that begin with an underscore are always reserved for
| use as identifiers with file scope in both the ordinary and tag name
| spaces.

This means that _MY_STRUCT is "always reserved for any use" and should
not be used by the programmer.
 
M

Mark A. Odell

(e-mail address removed) (Eric Gorr) wrote in


Personally, I prefer doing such things by writing:

typedef struct
{
...
} MY_STRUCT;

Yeah but then you can't have MY_STRUCT include a pointer to itself.

E.g.

typedef struct
{
MY_STRUCT *pMyStruct;
} MY_STRUCT;

Won't work.
 
M

Mark A. Odell

IIRC names with leading __ are reserved, one _ is perfectly ok IMO.

Not true, try defining _open() sometime and see if you get a conflict with
certain implementations.
Well, it works thanks. But I really don't like the fact
that the type and the struct have the same name.

Why? Anyhow the names don't have to be the same. Just do this:

typedef struct MyStructTag MyStruct;

struct MyStructTag
{
int a;
int b;
MyStruct *c;
};
And it breaks if they don't.

Works for me.
It's a matter of taste/style of course but I would still
like to hear about an option to get this working
with differently named struct/type.

See above or maybe you missed this when reading the FAQ:

http://www.eskimo.com/~scs/C-faq/q1.14.html
 
G

Goran Larsson

copx said:
Wow, it's even in the standard.

Why is that surprising? The standard is the first document I look in
to find out what is ok and what is not ok.
 
B

Ben Pfaff

copx said:
Now I would really like to know if there
is a common standard for such situations.
I mean if you want to name both the struct
and the type in a typedef struct construct.

Give them the same name.
 
A

Arthur J. O'Dwyer

Not true, try defining _open() sometime and see if you get a conflict with
certain implementations.

That's the fault of certain broken C implementations (*cough*MS*cough*),
not the programmer. The names reserved to the implementation are
those beginning with two underscores, or one underscore plus an uppercase
letter (or an uppercase E plus an uppercase letter, or...), but *not*
_open(). That's a perfectly valid (albeit dumb) name for a user function,
and shouldn't cause any errors in a decent ISO-compliant compiler in
conforming mode.
typedef struct MyStructTag MyStruct;

struct MyStructTag
{
int a;
int b;
MyStruct *c;
};

Or indeed

typedef struct MyStructTag
{
int a;
int b;
struct MyStructTag *c;
} MyStruct;

which is exactly what copx had in the
first place, but with better identifiers.
:)

-Arthur
 
G

Goran Larsson

Arthur J. O'Dwyer said:
The names reserved to the implementation are
those beginning with two underscores, or one underscore plus an uppercase
letter (or an uppercase E plus an uppercase letter, or...), but *not*
_open(). That's a perfectly valid (albeit dumb) name for a user function,
and shouldn't cause any errors in a decent ISO-compliant compiler in
conforming mode.

If you read the standard you will find that "_open" is reserved for
the implementation and is not a valid name for a user function.

From ANSI/ISO/IEC 9899-1999:

| 7.1.3 Reserved identifiers
| . . .
|
| - All identifiers that begin with an underscore and either an uppercase
| letter or another underscore are always reserved for any use.
|
| - All identifiers that begin with an underscore are always reserved for
| use as identifiers with file scope in both the ordinary and tag name
| spaces.
 
E

EPerson

Arthur J. O'Dwyer said:
That's the fault of certain broken C implementations (*cough*MS*cough*),
not the programmer. The names reserved to the implementation are
those beginning with two underscores, or one underscore plus an uppercase
letter (or an uppercase E plus an uppercase letter, or...), but *not*
_open(). That's a perfectly valid (albeit dumb) name for a user function,
and shouldn't cause any errors in a decent ISO-compliant compiler in
conforming mode.

Those implementations are not broken (in this respect). As quoted
elsethread, "All identifiers that begin with an underscore are always
reserved for use as identifiers with file scope in both the ordinary
and tag name spaces." Any function definition must be at file scope.
Therefore, if you define a function named _open, you invoke undefined
behavior.
 

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
473,774
Messages
2,569,598
Members
45,157
Latest member
MercedesE4
Top