Unknown features in gnu c: __attribute _ Mechanism

Source: Internet
Author: User
Tags deprecated

The 11th holiday was just a little fun. Today, I just calmed down and looked at the technology. I happened to encounter _ attribute __. although I have seen the Linux kernel code many times before, I still turned a blind eye to it, the following article is reproduced from the source code. The original Article is here.

A major feature of gnu c (but not known to beginners) is the _ attribute _ mechanism. _ Attribute _ FUNCTION attribute, variable attribute, and type attribute can be set ). Its writing features are: __attribute _ both have two underlines, and the opening and cutting are followed by a pair of original arc, which contains the corresponding _ attribute _ parameter, the syntax format is as follows:

_ Attribute _ (Attribute-list ))

In addition, it must be placed before the ";" at the end of the Declaration.

Function attribute

Function Attributes can help developers add some features to the function declaration, which makes the compiler more powerful in error checking. The _ attribute _ mechanism can also be easily compatible with non-GNU applications.

Gnu cc requires the-wall compiler to enable the function. This is a good way to control warning information. The following describes several common attribute parameters.

_ Attribute _ format. The _ attribute can add features similar to printf or scanf to the declared function. It allows the compiler to check whether the formatting string between the function declaration and the actually called function parameter matches. This function is very useful, especially for handling bugs that are hard to find. Format syntax format:

Format (archetype, string-index, first-to-check)

The format attribute tells the compiler to check the parameters of the function according to the format rules of the parameter table of printf, scanf, strftime, or strfmon. "Archetype" specifies the style. "string-index" specifies the first parameters of the Input Function to format the string; "First-to-check" specifies the number of parameters of the function to be checked according to the preceding rules.

The specific format is as follows:

_ Attribute _ (format (printf, m, n )))

_ Attribute _ (format (scanf, m, n )))

The meanings of M and N are as follows:

M: The parameters are formatted strings );

N: The first parameter in the parameter set, that is, the parameter "…" The first parameter is in the number of function parameters. Note that sometimes function parameters are "invisible" and will be mentioned later;

In terms of usage, __attribute _ (format (printf, m, n) is commonly used, but the other is rarely seen. The following example shows that myprint is a function defined by myself with variable parameters. Its function is similar to printf:

// M = 1; n = 2

Extern void myprint (const char * format,...) _ attribute _ (format (printf, 1, 2 )));

// M = 2; n = 3

Extern void myprint (int l, const char * format,...) _ attribute _ (format (printf, 2, 3 )));

Note that if myprint is a member function of a function, the values of M and N may be a bit "pretty". For example:

// M = 3; n = 4

Extern void myprint (int l, const char * format,...) _ attribute _ (format (printf, 3,4 )));

The reason is that the first parameter of the class member function is actually a "invisible" "This" pointer. (C ++ users all know the point this pointer. Do you still know it here ?)

Here is a test case: attribute. C. The Code is as follows:

extern void myprint(const char *format,...) __attribute__((format(printf,1,2)));void test(){myprint("i=%d\n",6);myprint("i=%s\n",6);myprint("i=%s\n","abc");myprint("%s,%d,%d\n",1,2);}

After GCC compilation, the system prompts a warning about format argument is not a pointer. If _ attribute _ (format (printf, 1, 2) is removed, the system will compile normally. Note that the compiler can only recognize the standard output library functions similar to printf.

There is also a _ attribute _ noreturn, which notifies the compiler function to never return a value. When a similar function needs to return a value but cannot run to the return value, it has exited, this attribute can avoid errors. The declaration formats of abort () and exit () in the C library function use this format, as shown below:

Extern void exit (INT) _ attribute _ (noreturn ));

Extern void abort (void) _ attribute _ (noreturn ));

For ease of understanding, you can refer to the following example:

// Name: noreturn. c; test _ attribute _ (noreturn) extern void myexit (); int test (int n) {If (n> 0) {myexit (); /* The program cannot arrive here */} elsereturn 0 ;}

The output result after compilation is as follows:

$ Gcc-wall-C noreturn. c

Noreturn. C: In function 'test ':

Noreturn. C: 12: Warning: control reaches end of non-void Function

Obviously, this is because a function is defined as a function with a returned value but has no returned value. Adding _ attribute _ (noreturn) can solve this problem.

There are also the attribute descriptions of _ attribute _ const,-finstrument-functions, no_instrument_function, and so on. If you are interested, you can refer to the original article.

Variable attribute)

The keyword _ attribute _ can also set attributes for variables or struct members. Here are several common parameter explanations. For more parameters, refer to the connection provided in the original article.

When using the _ attribute _ parameter, you can also add "_" (two underscores) before and after the parameter. For example, use _ aligned _ instead of aligned, in this way, you can use it in the corresponding header file without worrying about whether there is a macro definition with the same name in the header file.

Aligned (alignment)

This attribute specifies the smallest alignment format of a variable or struct Member, in bytes. For example:

Int X _ attribute _ (aligned (16) = 0;

The compiler allocates a variable in 16 bytes (note that byte is not bit) alignment. You can also set this attribute for the struct member variable. For example, to create a double-font-aligned int pair, you can write it like this:

Struct Foo {int X [2] _ attribute _ (aligned (8 )));};

As mentioned above, you can manually specify the alignment format. Similarly, you can also use the default alignment mode. If aligned is not followed by a specified number, the compiler will use the most useful aligned method based on your target machine. For example:

Short array [3] _ attribute _ (Aligned ));

Selecting the maximum alignment mode for the target machine can improve the efficiency of the copy operation. The aligned attribute makes the set object occupy more space. On the contrary, using packed can reduce the space occupied by the object.

It should be noted that the effectiveness of attribute attributes is also related to your connector. If your connector supports 16-byte alignment at most, defining 32-byte alignment at this time will not help.

This attribute enables the smallest alignment mode for variables or struct members, that is, one-byte alignment for variables and bit alignment for fields.

In the following example, if the x member variable uses this attribute, its value is placed after:

Struct Test

{

Char;

Int X [2] _ attribute _ (packed ));

};

Other optional attribute values include cleanup, common, nocommon, deprecated, mode, section, shared, tls_model, transparent_union, unused, vector_size, weak, dllimport, and dlexport.

Type attribute)

You can also set attributes for struct or union. There are roughly six parameter values that can be set: aligned, packed, transparent_union, unused, deprecated, and may_alias.

When using the _ attribute _ parameter, you can also add "_" (two underscores) before and after the parameter. For example, use _ aligned _ instead of aligned, in this way, you can use it in the corresponding header file without worrying about whether there is a macro definition with the same name in the header file.

Aligned (alignment)

This attribute sets an alignment format (in bytes) of the specified size. For example:

Struct s {short f [3];} _ attribute _ (aligned (8 )));

Typedef int more_aligned_int _ attribute _ (aligned (8 )));

This statement forces the compiler to make sure that variables of the type struct s or more-Aligned-int use an 8-byte aligned-int to allocate space.

As mentioned above, you can manually specify the alignment format. Similarly, you can also use the default alignment mode. If aligned is not followed by a specified number, the compiler will use the most useful aligned method based on your target machine. For example:

Struct s {short f [3];} _ attribute _ (Aligned ));

Here, if the size of sizeof (short) is 2 (byte), the size of S is 6. Take the power of 2 so that the value is greater than or equal to 6, then the value is 8, so the compiler sets the alignment of the S type to 8 bytes.

The aligned attribute makes the set object occupy more space. On the contrary, using packed can reduce the space occupied by the object.

It should be noted that the effectiveness of attribute attributes is also related to your connector. If your connector supports 16-byte alignment at most, defining 32-byte alignment at this time will not help.

Use this property to define the struct or union type and set the memory constraints for each variable of its type. When used in the enum type definition, it implies that the minimum complete type should be used (it indicates that the smallest integral type shoshould be used ).

In the following example, the values in the array of variables of the my-packed-struct type are closely tied, but the internal member variable S is not "pack ", if you want the internal member variables to be packed, you also need to use packed to constrain my-unpacked-struct.

Struct my_unpacked_struct

{

Char C;

Int I;

};

Struct my_packed_struct

{

Char C;

Int I;

Struct my_unpacked_struct S;

}__ Attribute _ (_ packed __));

Examples of variable attributes and type attributes

The following example uses the _ attribute to define some struct and Its variables, and provides output results and analysis of results.

// Program code: struct P {int A; char B; char C ;}__ attribute _ (aligned (4) pp; struct q {int; char B; struct n Qn; char C; }__ attribute _ (aligned (8) QQ; int main () {printf ("sizeof (INT) = % d, sizeof (short) = % d. sizeof (char) = % d \ n ", sizeof (INT), sizeof (short), sizeof (char); printf (" pp = % d, qq = % d \ n ", sizeof (PP), sizeof (qq); Return 0 ;}// output result: sizeof (INT) = 4, sizeof (short) = 2. sizeof (char) = 1PP = 8, QQ = 24

Analysis:

 

Sizeof (PP ):

Sizeof (A) + sizeof (B) + sizeof (c) = 4 + 1 + 1 = 6 <23 = 8 = sizeof (PP)

Sizeof (qq ):

Sizeof (A) + sizeof (B) = 4 + 1 = 5

Sizeof (qN) = 8; that is, qN adopts 8-byte alignment. Therefore, three spare bytes must be added after A and B before the Qn can be stored,

4 + 1 + (3) + 8 + 1 = 17

Because QQ uses 8-byte alignment, the QQ size must be an integer multiple of 8, that is, the QQ size is a minimum value greater than 17 and a multiple of 8.

17 <24 + 8 = 24 = sizeof (qq)

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.