Why do these C-structure definitions give warnings and errors?

Why do these two structure definitions compile fine:

struct foo { int a; } __attribute__((packed)); typedef struct __attribute__((packed)) { int a; } bar; 

While this gives a warning:

 typedef struct { int a; } baz __attribute__((packed)); warning: 'packed' attribute ignored [-Wattributes] 

And this gives an error and warning:

 typedef struct qux __attribute__((packed)) { int a; } qux; error: expected identifier or '(' before '{' token warning: data definition has no type or storage class [enabled by default] 

As a novice C programmer, the fact that the last two definitions don't work seems like a pretty arbitrary choice for parts of language developers / compiler compilers. Is there a reason for this? I am using gcc 4.7.3.

+4
source share
4 answers
 typedef struct __attribute__((packed)) { int a; } bar; 

vs

 typedef struct { int a; } baz __attribute__((packed)); 

In the first you said, “look at this anonymous structure with an attribute packaged that has a member a, and then create an alias for this structure and name it“ bar. ”The usual syntax for describing a structure without anonymity and its typedef is

 struct bar { int a; }; 

in the second ad you said, “look at this anonymous structure that has a member a, then create an alias for this structure and name it“ baz that is packed ”.

This does not work because you are trying to apply an attribute to an alias in a typedef, and not in a structure definition.

 typedef <entity> <alias>; 

I would suggest hitting someone who suggested you use typedef syntax to describe structures :)

+6
source

The reason it works in the first two instances is because __attribute__((packed)) can only be applied to struct , union or enum . In the first example, you declare a struct called foo , in the second you declare a struct called bar . In this second example, typedef converts a variable declaration into a type declaration.

In the third example, we declare a variable named baz and try to declare it as packed. Since the packaging information is tied to the type and not to the instance, this makes no sense, and the compiler ignores it.

See below for details on how gcc attributes work .

You really shouldn't even use packaged ones unless you know exactly what you are doing. Firstly, __attribute__ not standard C. If it is a gcc extension and therefore will not work with any other compiler.

In another case, there are very few situations when it is really necessary. For example, in your code, for example, it doesn’t work even in the first two instances, since packaging removes the space between members, and you only have one member in each struct . The reason packaging structures are not standard is because generic data types just work better when aligned at a certain boundary. For example, accessing int will work better if you are aligned with a memory cell that is a multiple of four. See the data structure alignment wiki entry for more information .

+1
source

The __attribute__((packed)) keyword is applied to a struct.

IN

 typedef struct { int a; } baz __attribute__((packed)); 

typedef associates baz with a structure - attributes appear after and nothing is applied - gcc ignores it. To fix this, allow typedef to bind the entire structure declaration, including the attribute, by placing baz after the attribute:

 typedef struct { int a; } __attribute__((packed)) baz; 

In the second example, the structure declaration is incorrect

 struct qux __attribute__((packed)) { int a; } 

how quz should appear after the attribute:

 struct __attribute__((packed)) qux { int a; } 

It is usually better to let the compiler optimize the structure and align the internal elements in memory so that the processor processes them more efficiently.

Packing the structure, however, can be important when creating a data structure that needs to be packaged to cope, for example, with the requirement of a driver.

+1
source

This is a rather strange question, because all this is very well explained in the manual. However, there is nothing arbitrary about this; you simply do not study the full use of this built-in keyword:

__attribute__(()) is a general purpose gcc extension. There are function attributes, type attributes, and variable attributes.

When you put the word __attribute__ , it determines what it refers to. You could have several __attribute__ in the given declaration, therefore it is not arbitrary to make some of them syntactically unacceptable to simplify internal parsing.

0
source

Source: https://habr.com/ru/post/1484003/


All Articles