C style structure declaration

I have a quick question about the style structure of C. I broke through the sample code and found a structure declared as follows:

typedef struct _STRUCTNAME { // struct contents } STRUCTNAME; 

Note the lack of underline the second time STRUCTNAME appears. I realized that this would declare one _STRUCTNAME called STRUCTNAME, and no objects of this structure would be created.

However, this does not seem to be the case. A structure of this type has never been actually implemented in code, except in one place: in a global array of such objects that were used in random places:

 const struct STRUCTNAME ARRAYNAME[] = { // various STRUCTNAMEs declared here }; 

Note the lack of underscore again (which I thought was the name of the object-object)?

Is my understanding completely disabled?

Can anyone explain?

+8
c struct
source share
5 answers
 typedef struct _STRUCTNAME { // struct contents } STRUCTNAME; 

This piece of code performs two functions:

  • Defines a structure named struct _STRUCTNAME and
  • Creates a typedef for this structure called STRUCTNAME .

The reason for this is that in the right C code, the way you would otherwise declare a struct (like above) would be this:

 struct _STRUCTNAME structInstance; 

However, using typedef , you can simply use the following:

 STRUCTNAME structInstance; 

The same is true for enum declarations.

+7
source share

STRUCTNAME is the name of typedef.

_STRUCTNAME is a "tag" for a structure that resides in a different namespace.

Prior to ANSI standardization, the structure tag namespace was not separate in many compilers, so this should be different to prevent name clashes with typedef. However, since standardization is not necessary, the tag name should be different.

You see this idiom often used in Windows code, no doubt, because it was in many examples from the SDK. Raymond Chen wrote a blog post about this a while ago:

In addition, I am sure there will be some comments on how the _STRUCTNAME identifier _STRUCTNAME reserved for implementation, so it is not recommended to use this form in any case.

+4
source share

Michael Barr said:

In addition, I am sure there will be some comments on how the _STRUCTNAME identifier _STRUCTNAME reserved for implementation, so it is not recommended to use this form in any case.

OK, I play (but I need formatting so you get the answer):

The language standard is a contract between the compiler and the compiler, where each promises performs and does not perform certain actions.

Most identifiers starting with _ are reserved for implementation — including all identifiers starting with _ followed by an uppercase letter. This means that the compiler author is allowed to use them for any purpose, because the user compiler has promised not to use them.

Compilers - users who break their promise get strange results.

Conversely, all identifiers that the [applicable] standard does not reserve for implementation will be guaranteed to be available to the user compiler, since the author compiler promised not to use them.

Compiler authors who break their promise receive a refund when a valid code gets strange results.

My preference is to put trailing _ tags on tags, enable defenders, etc., so that I stay out of the implementation space; Thus:

 typedef struct STRUCTNAME_ { // struct contents } STRUCTNAME; 

(Some purists frowned at typedef as just syntactic sugar, but C needs a little sugar here and there, otherwise it might seem pretty bland.)

+2
source share

I believe your confusion is due to why the list of identifiers at the end of the struct definition is not an instance of instances. The reason is because you included the typedef keyword.

Consider syantax for typedef :

 typedef type-definition identifier; 

What you have done, you are given a struct as a type definition. Instead of instantiating, you define a type. Contrast this with instance instances, where the struct simply defines the inline type:

 struct STRUCTNAME { // struct contents } myStruct, *ptr, alsoMyStruct; 

If you do not include the typedef keyword, the identifier simply indicates the instances as usual.

0
source share
 const struct STRUCTNAME ARRAYNAME[] = { // various STRUCTNAMEs declared here }; 

the above code is not going to compile for an incomplete type for an array. I think they should be

 const struct _STRUCTNAME ARRAYNAME[] = ... 

Alternatively, you can use typedefs without specifying the struct keyword

 const STRUCTNAME ARRAYNAME[] = 
0
source share

All Articles