GCC's __attribute__ extension capabilities

Source: Internet
Author: User
Tags deprecated function definition
Summary:
In the study of Linux kernel code and some Open-source software source, you can often see the relevant use of __attribute__. This article unifies own study experience, has introduced in detail the __attribute__ related grammar and its use.
----------------------------------------------------------------
Statement:
This article is original, welcome reprint, Reprint please keep the following information
Author: Nie Fei (Afreez) Beijing-Zhongguancun
Contact: afreez@sina.com (Welcome to communicate with the author)
Initial release Date: 2006-06-17
No word of business without my consent
The nature of the business or profit, otherwise, the author has the right to investigate the relevant responsibility.
------------------------------------------------------------------------------------------------------

One of the major features of GNU C (which is not known to beginners) is the __attribute__ mechanism. __ATTRIBUTE__ can set function attributes, variable attributes (Variable attribute), and type attributes.
__attribute__ writing feature is: __attribute__ before and after there are two underline, and cut followed by a pair of original brackets, brackets inside the corresponding __attribute__ parameters.
The __ATTRIBUTE__ syntax format is:
__attribute__ ((attribute-list))

Its position constraint is:
Put on the tail of the Declaration ";" before.

function attributes (functions attribute)
Function properties can help developers add features to function declarations, which can make the compiler more powerful in error checking. The __attribute__ mechanism is also easily compatible with non-GNU applications.

GNU cc needs to use the –wall compiler to hit the deserved function, which is a good way to control the warning message. Here are a few common property parameters.

__attribute__ format
The __attribute__ property can add features like printf or scanf to the declared function, which enables the compiler to check whether the formatted string is matched between the function declaration and the actual invocation parameters of the function. This feature is useful, especially when dealing with bugs that are hard to find.
The syntax for format is:
Format (archetype, String-index, First-to-check)
The Format property tells the compiler to check the parameters of the function according to the table-style rules for the parameters of printf, scanf, strftime, or Strfmon. "archetype" specifies which style; "String-index" specifies that the first parameter of the Passed-in function is a formatted string, and "First-to-check" specifies that the first few arguments of the function be checked against the preceding rule.
The specific use of the format is as follows:

__ATTRIBUTE__ ((Format (printf,m,n))
__ATTRIBUTE__ ((Format (scanf,m,n))
Where the argument m and N means:
M: The first parameters are formatted strings (format string);
N: The first parameter in the parameter set, the argument "..." in the sum of the number of function parameters, note that there are sometimes "stealth" in the function parameters, which will be mentioned later;
In use, __attribute__ (format (printf,m,n)) is commonly used, while the other is rarely seen. Here's an example of a function that has a variable parameter defined for itself, and functions like printf: myprint
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));
The special note is that if Myprint is a member function of a class, then the value of M and n can be somewhat "poised", for example:
M=3;n=4
extern void Myprint (int l,const char *format,...) __attribute__ ((Format (printf,3,4));
The reason for this is that the first argument of a class member function is actually a "this" pointer to "stealth". (A little C + + base all know point this pointer, do not know you here also know.) )
Here is a test case: ATTRIBUTE.C, the code is as follows:
1:
2:extern void Myprint (const char *format,...) __attribute__ ((Format (printf,1,2));
3:
4:void Test ()
5:{
6:myprint ("i=%d/n", 6);
7:myprint ("i=%s/n", 6);
8:myprint ("i=%s/n", "abc");
9:myprint ("%s,%d,%d/n", 1,2);
10:}
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,1,2)) and recompile, after running $gcc–wall–c attribute.c attribute, Does not output any warning messages.
Note that by default, the compiler is a "standard" library function that recognizes similar printf.

__attribute__ Noreturn

This property notifies the compiler that the value is never returned and that it avoids error messages when it encounters a function that needs to return a value but is not able to run to the return value. The Declaration format for abort () and exit () in the C library function takes this format, as follows:
extern void exit (int) __attribute__ ((noreturn));
extern void abort (void) __attribute__ ((noreturn));

To facilitate understanding, you can refer to the following examples:
NAME:NORETURN.C Test __attribute__ ((noreturn))
extern void Myexit ();
int test (int n)
{
if (n > 0)
{
Myexit ();
/* The program is not possible to get here *
}
Else
return 0;
}

The output information displayed by the compilation is:
$GCC –wall–c NORETURN.C
noreturn.c:in function ' Test ':
Noreturn.c:12:warning:control reaches end of non-void function
The warning message is also well understood, because you define a function with a return value, but you may not have the return value, and the program certainly doesn't know what to do.
Adding __attribute__ (noreturn) can be a good deal of a problem like this. Put
extern void Myexit ();

Modified to:
extern void Myexit () __attribute__ ((noreturn));
Later, the compilation does not appear with a warning message.

__attribute__ Const

This property can only be used on functions with numeric type parameters. When a function with a numeric parameter is repeatedly called, because the return value is the same, the compiler can then optimize the process so that, in addition to the first operation, other results that only need to be returned for the first time can be improved. This property is primarily applicable to functions that do not have static state and side effects, and the return value relies solely on the input parameters.
To illustrate the problem, here's a very "bad" example that repeats a function with the same parameter value, as follows:
extern int square (int n) __attribute__ (const);
...
for (i = 0; I <>
{
Total = Square (5) + i;
}
By adding a __attribute__ (const) Declaration, the compiler invokes only one function at a time, and then just gets the same return value directly.
In fact, the const parameter cannot be used in a function with a pointer type parameter because it affects not only the parameter values of the function, but also the data that the parameter points to, which can have serious or even unrecoverable consequences for the code itself.
Also, a function with this property cannot have any side effects or a static state, so a function similar to GetChar () or time () is not appropriate for this property.


-finstrument-functions
This parameter enables the program to generate a instrumentation call at compile time, at the entry and exit of the function. Just after the function entry and just before the function exits, the following profiling function is invoked using the address and invocation address of the current function. (On some platforms, __builtin_return_address cannot work beyond the scope of the current function, so calling address information may not be valid 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);
Where the first parameter THIS_FN is the starting address of the current function, it can be found in the symbol table, and the second parameter call_site refers to the address of the call.
Instrumentation can also be used in inline functions that are expanded in other functions. Conceptually, the profiling call will indicate where to enter and exit the inline function. This means that the function must have an addressable form. If the function contains inline, and all programs that use the function have to expand the inline, this adds additional code length. If you want to use the extern inline declaration in C code, you must provide an addressable form of this function.
You can specify the No_instrument_function property on a function, in which case the instrumentation operation is not performed. For example, you can use the No_instrument_function property in the following situations: The Profiling function listed above, the high priority interrupt routine, and any functions that do not guarantee a normal profiling call.

No_instrument_function
If-finstrument-functions is used, the profiling function is called at the entry and exit points of the most user-compiled functions. Using this property, the instrument operation is not performed.

Constructor/destructor
If the function is set to the constructor property, the function is executed automatically before the main () function executes. Similarly, if a function is set to the Destructor property, the function is automatically executed after the main () function executes or when exit () is invoked. Functions that have such properties are often implicitly used in the initialization data of a program.
These two properties are not yet implemented in object-oriented C.
I think this attribute is more useful, such as to initialize some global data in C file, you can define such a function to fix, for example:
extern void Aconstructor () __attribute__ ((constructor));
int aaa=0;
void Aconstructor ()
{
aaa=12345;
}

int main ()
{
printf ("%d", AAA);
return 0;
}

After running, it was found that AAA was really initialized to 12345.


Use multiple properties at the same time

You can use multiple __attribute__ in the same function declaration, and this is very common in practical applications. Using the method, you can choose two individual __attribute__, or write them together, you can refer to the following example:
/* Send a message similar to printf to stderr and exit * *
extern void die (const char *format, ...)
__attribute__ ((noreturn))
__ATTRIBUTE__ (Format (printf, 1, 2));
or write

extern void die (const char *format, ...)
__ATTRIBUTE__ ((noreturn, Format (printf, 1, 2));

If the custom function with this property is appended to the header file of the library, the program that calls the function should check accordingly.

Compatibility with non-GNU compilers

Fortunately, __attribute__ is designed to be very ingenious and easy to keep compatible with other compilers, that is, if you work on other non-GNU compilers, you can easily ignore the attribute. Even if __attribute__ uses multiple parameters, it can be easily handled using a pair of parentheses, such as
* * If the use of non-GNU C, then ignore __attribute__ * *
#ifndef __gnuc__
# define __ATTRIBUTE__ (x)/*nothing*/
#endif

It should be explained that __attribute__ applies to the declaration of a function rather than to the definition of a function. So, when you need a function that uses this property, you must declare it 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 * *
}


More attribute meaning reference:
Http://gcc.gnu.org/onlinedocs/gcc-4.0.0/gcc/Function-Attributes.html

Variable properties (Variable Attributes)

Keyword __attribute__ can also set properties on a variable (variable) or struct Member (structure field). Here are some common parameters to explain, more parameters can refer to the connection given in this article.
When using the __attribute__ parameter, you can also add "__" (two underscores) before and after the parameter, for example, using __aligned__ instead of aligned, so that you can use it in the header file without being concerned about the macro definition in the header file that has a duplicate name.
Aligned (alignment)
This property sets the minimum alignment format, in bytes, of a variable or struct member. For example:
int x __attribute__ ((aligned (16)) = 0;

The compiler assigns a variable in 16 bytes (note that byte byte is not bit) aligned. You can also set this property on a struct member variable, for example, to create a two-word-aligned int pair that can be written like this:
struct Foo {int x[2] __attribute__ ((aligned (8)));

As mentioned above, you can manually specify the alignment format, and you can also use the default alignment. If the aligned is not followed by a specified numeric value, the compiler will use the largest and most beneficial alignment according to your target machine. For example:
Short array[3] __attribute__ ((aligned));

You can increase the efficiency of copy operations by selecting the maximum alignment for the target machine.
The aligned property makes the object being set occupy more space, instead, using packed can reduce the space occupied by the object.
It is important to note that the validity of attribute attributes is also related to your connector, and if your connector supports only 16-byte alignment, then it is useless to define 32-byte alignment at this point.
Packed

Use this property to make a variable or struct member use the smallest alignment, that is, a byte alignment to the variable, and a bit alignment for the field (field).
In the following example, the X member variable uses this property, and its value is placed tightly behind a:
struct test
{
Char A;
int x[2] __attribute__ ((packed));
};


Other optional property values can also be: cleanup,common,nocommon,deprecated,mode,section,shared, tls_model,transparent_union,unused,vector_ Size,weak,dllimport,dlexport and so on,
For more information, refer to:

Http://gcc.gnu.org/onlinedocs/gcc-4.0.0/gcc/Variable-Attributes.html#Variable-Attributes

Type attribute

Keyword __attribute__ can also set properties on the structure body (struct) or the common Body (Union). Roughly six parameter values can be set, namely: 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, using __aligned__ instead of aligned, so that you can use it in the header file without being concerned about the macro definition in the header file that has a duplicate name.
Aligned (alignment)

This property sets the alignment (in bytes) of a specified size, for example:
struct S {short f[3];} __attribute__ ((aligned (8));
typedef int MORE_ALIGNED_INT __ATTRIBUTE__ ((aligned (8));
The declaration forces the compiler to ensure (to the best of its ability) that variables of variable type struct s or more-aligned-int use 8-byte alignment when allocating space.
As mentioned above, you can manually specify the alignment format, and you can also use the default alignment. If the aligned is not followed by a specified numeric value, the compiler will use the largest and most beneficial alignment according to your target machine. For example:
struct S {short f[3];} __attribute__ ((aligned));
Here, if the size of sizeof (short) is 2 (byte), then the size of S is 6. If the value of 2 is greater than or equal to 6, the value is 8, so the compiler sets the alignment of type S to 8 bytes.
The aligned property makes the object being set occupy more space, instead, using packed can reduce the space occupied by the object.
It is important to note that the validity of attribute attributes is also related to your connector, and if your connector supports only 16-byte alignment, then it is useless to define 32-byte alignment at this point.
Packed
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 is implied that the smallest complete type should be used (it indicates that the smallest integral type should is used).
In the following example, the values in the MY-PACKED-STRUCT type variable array will be tightly pressed together, but the internal member variable s will not be "pack", if the inner member variable is expected to be packed, My-unpacked-struct also need to use packed for the appropriate constraints.

struct MY_UNPACKED_STRUCT
{
char c;
int i;
};

struct MY_PACKED_STRUCT

{
char c;
int i;
struct my_unpacked_struct s;
}__attribute__ ((__packed__));

The meanings of other attributes are as follows:

Http://gcc.gnu.org/onlinedocs/gcc-4.0.0/gcc/Type-Attributes.html#Type-Attributes
Variable attribute and type attribute example

The following example uses the __attribute__ attribute to define some structures and their variables, and gives an analysis of the output and the results.

The program code is:
struct P
{
int A;
Char b;
char c;
}__ATTRIBUTE__ ((Aligned (4)) pp;

struct Q
{
int A;
Char b;
struct P 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 results:
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<8
Related Article

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.