转载请注明来源:http://blog.csdn.net/imred/article/details/50166063
今天试着读了glibc的一些源代码,只能用头大来形容我的感受,见到了各种奇怪的标识符,各种宏定义,总之很难通顺的读下去。我决定仔细看看这些奇怪的东西,将出现较频繁的内容大致了解一下。今天我们来看看其中出现次数相当多的“__attribute__”标识符。
举一个我看到的例子:
extern void longjmp (struct __jmp_buf_tag __env[1], int __val)
__THROW __attribute__ ((__noreturn__));
函数声明右括号后面还跟着一大坨东西,其中一个就是“__attribute__”,这让没读过多少别人代码的我很是费解,最终在gcc官方的手册里找到了关于它的解答,在线版的在这里:https://gcc.gnu.org/onlinedocs/gcc-5.2.0/gcc/Function-Attributes.html#Function-Attributes。本文的内容就是对这部分内容开头的一部分翻译,没有更深入的了解它,读通代码才是我的目的。
先把英文版搬上来:
In GNU C, you declare certain things about functions called in your program which help the compiler optimize function calls and check your code more carefully.
The keyword __attribute__ allows you to specify special attributes when making a declaration. This keyword is followed by an attribute specification inside double parentheses. The following attributes are currently defined for functions on all targets: aligned, alloc_size, alloc_align, assume_aligned, noreturn, returns_twice, noinline, noclone, no_icf, always_inline, flatten, pure, const, nothrow, sentinel, format, format_arg, no_instrument_function, no_split_stack, section, constructor, destructor, used, unused, deprecated, weak, malloc, alias, ifunc, warn_unused_result, nonnull, returns_nonnull, gnu_inline, externally_visible, hot, cold, artificial, no_sanitize_address, no_address_safety_analysis, no_sanitize_thread, no_sanitize_undefined, no_reorder, bnd_legacy, bnd_instrument, stack_protect, error and warning. Several other attributes are defined for functions on particular target systems. Other attributes, including section are supported for variables declarations (see Variable Attributes), labels (see Label Attributes) and for types (see Type Attributes).
GCC plugins may provide their own attributes.
You may also specify attributes with ‘__’ preceding and following each keyword. This allows you to use them in header files without being concerned about a possible macro of the same name. For example, you may use __noreturn__ instead of noreturn.
See Attribute Syntax, for details of the exact syntax for using attributes.
下面是我的翻译和注解:
在GNU C中,如果你把调用的函数声明得具体一些,编译器就能更好地优化你的函数调用以及更仔细地检查你的代码。
关键字 __attribute__ 允许你在作声明时指定一些特殊的属性。(这里的keyword就是指它是C语言关键字之一吗?它是用来指导编译器的,所以应该并不是在某个头文件中声明的标识符,就算是也应该是大写的,总之我试了一下编译一个带 __attribute__ 声明的C程序是可以直接编译过的。)这个关键字后面跟着一个双层的括号,括号里面是指定的属性。(就比如上面我提到的那个例子。)下面这些为函数定义的属性适用于所有的目标(系统):
aligned, alloc_size, alloc_align, assume_aligned, noreturn, returns_twice, noinline, noclone, no_icf, always_inline, flatten, pure, const, nothrow, sentinel, format, format_arg, no_instrument_function, no_split_stack, section, constructor, destructor, used, unused, deprecated, weak, malloc, alias, ifunc, warn_unused_result, nonnull, returns_nonnull, gnu_inline, externally_visible, hot, cold, artificial, no_sanitize_address, no_address_safety_analysis, no_sanitize_thread, no_sanitize_undefined, no_reorder, bnd_legacy, bnd_instrument, stack_protect, error, warning.
还有一些属性用于特定的目标系统。除了为函数定义的属性,还有一些属性用于其他内容的声明,比如变量声明(见Variable Attributes),标签(见Label Attributes),类型(Type Attributes)。
GCC 的插件可能会提供对它们自定义的属性的支持。
你在指定属性时,你可以在属性的前后加上“__”,防止这些属性的名字和头文件中的可能存在的同名宏定义产生冲突。(比如声明成void foo() __attribute__((__noreturn__));而不是void foo() __attribute__((noreturn));)
对于使用这些属性的具体语法,请参阅Attribute Syntax一节。
以上就是关于这个“__attribute__”的大致内容了,下面是紧跟着上面内容的各种属性的第一个属性,来帮大家更好的理解一下。
alias (“target”)
alias属性声明的内容会被作为另一个符号的别名,这个别名必须要我们来指定。下面是一个例子:
void __f () { /* Do something. */; }
void f () __attribute__ ((weak, alias (“__f”)));
‘f’就会被当做‘__f’的别名来看待。在C++里,指定的目标必须存在,如果‘__f’没有定义就会产生一个错误。
并不是所有的机器都支持这个属性。
以上就是所有内容了,希望能对你有所帮助。
转载请注明来源:http://blog.csdn.net/imred/article/details/50166063