During kernel, we noticed that some functions will add _ attribute _ (unused )),
Relevant explanations are found in the GCC manual:
Unused: This attribute, attached to a function, means that the function is meant to be
Possibly unused. GCC will not produce a warning for this function.
========================================================== ========================================================
Used: This attribute, attached to a function, means that code must be emitted for
Function even if it appears that the function is not referenced. This is useful,
For example, when the function is referenced only in inline assembly.
Indicates that the function or variable may not be used. This attribute can prevent the compiler from generating warning information.
Sometimes some function calls are temporarily blocked during program debugging to get the above errors and prevent compilation. To "cheat" GCC,
1. _ attribute __
GNU CA major feature (but not known to beginners) is the _ attribute _ mechanism.
_ Attribute _ FUNCTION attribute, variable attribute, and type attribute can be set)
There are two underscores (_ attribute _) on the front and back, and a pair of original arc will be followed. The _ attribute _ parameter in the arc is
_ Attribute __Syntax format:
_ Attribute _ (Attribute-list ))
Function attribute helps developers add some features to function declaration, which makes the compiler more powerful in error checking.
The _ attribute _ mechanism is also easily compatible with non-GNU applications.
Gnu cc requires the use of-wall, which is a good way to control warning information. The following describes several common attribute parameters.
2. Format
This attribute allows the compiler to check whether the formatted string between the function declaration and the actually called function parameter match. It can add features similar to printf or scanf to declared functions, which is very useful, especially to handle bugs that are hard to find.
FormatSyntax 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: Specify the style;
String-index: Specify the 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 "…" Number of the first parameter in
Note: Sometimes the function parameters are "invisible", which 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 an "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 running $ gcc-wall-C attribute. c attribute, the output result is:
Attribute. C: In function 'test ':
Attribute. C: 7: Warning: format argument is not a pointer (ARG 2)
Attribute. C: 9: Warning: format argument is not a pointer (ARG 2)
Attribute. C: 9: Warning: Too few arguments for format
If the function declaration in attribute. c removes _ attribute _ (format (printf,) and re-compiles,
After $ gcc-wall-C attribute. c attribute is run, no warning information is output.
Note that by default, the compiler recognizes "standard" library functions similar to printf.
3. noreturn
This attribute notifies the compiler function to never return a value.
This attribute can avoid errors when a function needs to return a value but has not been run at the return value. The declaration formats of abort () and exit () in the C library function use this format.:
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 */
}
Else
{
Return 0;
}
}
Compile$ Gcc-wall-C noreturn. cThe output information is as follows:
Noreturn. C: In function 'test ':
Noreturn. C: 12: Warning: control reaches end of non-void Function
The warning information is also well understood, because you have defined a function test with returned values, but it may not return values. Of course, the program does not know what to do! When _ attribute _ (noreturn) is added, the problem like this can be well handled. SetExtern void myexit ();To:
Extern void myexit () _ attribute _ (noreturn ));
After compilation, no warning information will appear.
4. Const
This attribute can only be used for functions with numeric parameters. When a function with numeric parameters is repeatedly called, the returned values are the same. Therefore, the compiler can optimize the processing. In addition to the first operation, the compiler only needs to return the first result.
This attribute is mainly applicable to functions without static state and side effects, and the return value only depends on the input parameters. To illustrate the problem, the following is a very "bad" example. This example will repeatedly call a function with the same parameter value, as shown below:
Extern int square (int n) _ attribute _ (const ));
For (I = 0; I <100; I ++)
{
Total + = square (5) + I;
}
Add the _ attribute _ (const) Declaration. The Compiler only calls the function once and then directly obtains the same return value.
In fact, the const parameter cannot be used in a function with a pointer type parameter, because this attribute not only affects the parameter value of the function, but also affects the data pointed to by the parameter, it may have serious or unrecoverable consequences for the Code itself. In addition, functions with this attribute cannot have any side effects or static states. functions similar to getchar () or time () are not suitable for this attribute.
5. finstrument-Functions
This parameter allows the program to generate an instrumentation call at the function entry and exit during compilation. Just after the function entry and just before the function exit, the following profiling function will be called using the current function address and call address. (On some platforms, __builtin_return_address cannot work normally beyond the current function range, so calling address information may be invalid for the profiling function)
Void _ cyg_profile_func_enter (void * this_fn, void * call_site );
Void _ cyg_profile_func_exit (void * this_fn, void * call_site );
Among them, the first parameter this_fn is the starting address of the current function, which can be found in the symbol table; the second parameter call_site is the address of the call.
6. Instrumentation
It can also be used for inline functions expanded in other functions. In terms of concept, the profiling call will indicate where to enter and exit the inline function. This means that such functions must be addressable. If the function contains inline, and all programs that use this function need to expand this inline, this will increase the code length. To use extern inline declaration in C code, you must provide the addressable form of this function.
You can specify the no_instrument_function attribute for a function. In this case, no instrumentation operation is performed. For example, you can use the no_instrument_function attribute in the following situations: the profiling function listed above, the Interrupt Routine with a high priority, and any function that cannot guarantee normal profiling calls.
No_instrument_function
If-finstrument-functions is used, the profiling function will be called at the entry and exit points of the function compiled by most users. With this attribute, no instrument operation is performed.
7. constructor/destructor
If the function is set to the constructor attribute, the function is automatically executed before the main () function is executed. Similarly, if a function is set to the Destructor attribute, the function is automatically executed after the main () function is executed or after the exit () function is called. Functions with such attributes are often implicitly used in the initialization data of the program. These two attributes are not implemented in Object-Oriented C.
8. Use multiple attributes at the same time
Multiple _ attribute __s can be used in the same function declaration, which is very common in actual applications. In terms of usage, you can select two separate _ attribute __, or write them together. You can refer to the following example:
Extern void die (const char * format ,...) _ attribute _ (noreturn) _ attribute _ (format (printf, 1, 2 )));
Or write it
Extern void die (const char * format,...) _ attribute _ (noreturn, format (printf, 1, 2 )));
If the custom function with this attribute is appended to the header file of the library, the program that calls this function must perform corresponding checks.
9. Compatibility with non-GNU Compilers
The Design of _ attribute _ is very clever, and it is easy to maintain compatibility with other compilers. That is to say, if you work on other non-GNU compilers, you can easily ignore this attribute. Even if _ attribute _ uses multiple parameters, a pair of circular arc can be easily used for processing. For example:
/* If non-gnu c is used, ignore _ attribute __*/
# Ifndef _ gnuc __
# DEFINE _ attribute _ (x)/* nothing */
# Endif
It should be noted that __attribute _ applies to the declaration of functions rather than the definition of functions. Therefore, when you need to use the function of this attribute, it must be declared in the same file, for example:
/* Function declaration */
Void die (const char * format,...) _ attribute _ (noreturn) _ attribute _ (format (printf, 1, 2 )));
Void die (const char * format ,...)
{/* Function definition */}
For more attributes, refer:Http://gcc.gnu.org/onlinedocs/gcc-4.0.0/gcc/Function-Attributes.html
10. variable attributes)
You can also set attributes for variables or structure fields.
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.
11. 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,May_alias
12. 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 )));
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. 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. For example:
Struct s {short f [3];} _ attribute _ (Aligned ));
As shown above, aligned is not followed by a specified number. The compiler will use the largest and most beneficial aligned mode based on your target machine.
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 )));};
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.
13. Packed
This attribute enables the smallest alignment mode for variables or struct members, that is, one-byte alignment for variables and bit alignment for fields. 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, if the x member variable uses this attribute, its value is placed after:
Struct Test
{
Char;
Int X [2] _ attribute _ (packed ));
};
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, my-unpacked-struct also needs to use packed for corresponding constraints.
Struct my_packed_struct
{
Char C;
Int I;
Struct my_unpacked_struct S;
}__ 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.
For more details, refer:Http://gcc.gnu.org/onlinedocs/gcc-4.0.0/gcc/Variable-Attributes.html#Variable-Attributes
14. 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.
The program code is:
Struct P
{
Int;
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) = 1
Pp = 8, QQ = 24
Analysis:
Sizeof (PP ):
Sizeof (A) + sizeof (B) + sizeof (c) = 4 + 1 + 1 = 6 <2 ^ 3 = 8 = sizeof (PP)
Sizeof (qq ):
Sizeof (A) + sizeof (B) = 4 + 1 = 5
Sizeof (qN) = 8;
That is, qN adopts eight-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 <2 ^ 4 + 8 = 24 = sizeof (qq)
For more details, see: http://gcc.gnu.org/
Below are some convenient connections:
GCC 4.0 Function Attributes
GCC 4.0 variable attributes
GCC 4.0 type attributes
15. Ref
Brief _ attribute _ Introduction: http://www.unixwiz.net/techtips/gnu-c-attributes.html
Introduction to _ attribute _: http://gcc.gnu.org/
_ Attribute _ mechanism Introduction