Attribute Syntax
Attribute Syntax
This section describes the syntax with which __attribute__
may be used, and the constructs to which attribute specifiers bind, for the C language. Some details may vary for C++ and Objective-C. Because of infelicities in the grammar for attributes, some forms described here may not be successfully parsed in all cases.
There are some problems with the semantics of attributes in C++. For example, there are no manglings for attributes, although they may affect code generation, so problems may arise when attributed types are used in conjunction with templates or overloading. Similarly, typeid
does not distinguish between types with different attributes. Support for attributes in C++ may be restricted in future to attributes on declarations only, but not on nested declarators.
See Function Attributes, for details of the semantics of attributes applying to functions. See Variable Attributes, for details of the semantics of attributes applying to variables. See Type Attributes, for details of the semantics of attributes applying to structure, union and enumerated types.
An attribute specifier is of the form __attribute__ ((
attribute-list))
. An attribute list is a possibly empty comma-separated sequence of attributes, where each attribute is one of the following:
- Empty. Empty attributes are ignored.
- A word (which may be an identifier such as
unused
, or a reserved word such asconst
). - A word, followed by, in parentheses, parameters for the attribute. These parameters take one of the following forms:
- An identifier. For example,
mode
attributes use this form. - An identifier followed by a comma and a non-empty comma-separated list of expressions. For example,
format
attributes use this form. - A possibly empty comma-separated list of expressions. For example,
format_arg
attributes use this form with the list being a single integer constant expression, andalias
attributes use this form with the list being a single string constant.
- An identifier. For example,
An attribute specifier list is a sequence of one or more attribute specifiers, not separated by any other tokens.
In GNU C, an attribute specifier list may appear after the colon following a label, other than a case
or default
label. The only attribute it makes sense to use after a label is unused
. This feature is intended for code generated by programs which contains labels that may be unused but which is compiled with -Wall. It would not normally be appropriate to use in it human-written code, though it could be useful in cases where the code that jumps to the label is contained within an #ifdef
conditional. GNU C++ only permits attributes on labels if the attribute specifier is immediately followed by a semicolon (i.e., the label applies to an empty statement). If the semicolon is missing, C++ label attributes are ambiguous, as it is permissible for a declaration, which could begin with an attribute list, to be labelled in C++. Declarations cannot be labelled in C90 or C99, so the ambiguity does not arise there.
An attribute specifier list may appear as part of a struct
, union
or enum
specifier. It may go either immediately after the struct
, union
or enum
keyword, or after the closing brace. The former syntax is preferred. Where attribute specifiers follow the closing brace, they are considered to relate to the structure, union or enumerated type defined, not to any enclosing declaration the type specifier appears in, and the type defined is not complete until after the attribute specifiers.
Otherwise, an attribute specifier appears as part of a declaration, counting declarations of unnamed parameters and type names, and relates to that declaration (which may be nested in another declaration, for example in the case of a parameter declaration), or to a particular declarator within a declaration. Where an attribute specifier is applied to a parameter declared as a function or an array, it should apply to the function or array rather than the pointer to which the parameter is implicitly converted, but this is not yet correctly implemented.
Any list of specifiers and qualifiers at the start of a declaration may contain attribute specifiers, whether or not such a list may in that context contain storage class specifiers. (Some attributes, however, are essentially in the nature of storage class specifiers, and only make sense where storage class specifiers may be used; for example, section
.) There is one necessary limitation to this syntax: the first old-style parameter declaration in a function definition cannot begin with an attribute specifier, because such an attribute applies to the function instead by syntax described below (which, however, is not yet implemented in this case). In some other cases, attribute specifiers are permitted by this grammar but not yet supported by the compiler. All attribute specifiers in this place relate to the declaration as a whole. In the obsolescent usage where a type of int
is implied by the absence of type specifiers, such a list of specifiers and qualifiers may be an attribute specifier list with no other specifiers or qualifiers.
At present, the first parameter in a function prototype must have some type specifier which is not an attribute specifier; this resolves an ambiguity in the interpretation of void f(int (__attribute__((foo)) x))
, but is subject to change. At present, if the parentheses of a function declarator contain only attributes then those attributes are ignored, rather than yielding an error or warning or implying a single parameter of type int, but this is subject to change.
An attribute specifier list may appear immediately before a declarator (other than the first) in a comma-separated list of declarators in a declaration of more than one identifier using a single list of specifiers and qualifiers. Such attribute specifiers apply only to the identifier before whose declarator they appear. For example, in
__attribute__((noreturn)) void d0 (void),
__attribute__((format(printf, 1, 2))) d1 (const char *, ...),
d2 (void)
the noreturn
attribute applies to all the functions declared; the format
attribute only applies to d1
.
An attribute specifier list may appear immediately before the comma, =
or semicolon terminating the declaration of an identifier other than a function definition. Such attribute specifiers apply to the declared object or function. Where an assembler name for an object or function is specified (see Asm Labels), the attribute must follow the asm
specification.
An attribute specifier list may, in future, be permitted to appear after the declarator in a function definition (before any old-style parameter declarations or the function body).
Attribute specifiers may be mixed with type qualifiers appearing inside the []
of a parameter array declarator, in the C99 construct by which such qualifiers are applied to the pointer to which the array is implicitly converted. Such attribute specifiers apply to the pointer, not to the array, but at present this is not implemented and they are ignored.
An attribute specifier list may appear at the start of a nested declarator. At present, there are some limitations in this usage: the attributes correctly apply to the declarator, but for most individual attributes the semantics this implies are not implemented. When attribute specifiers follow the *
of a pointer declarator, they may be mixed with any type qualifiers present. The following describes the formal semantics of this syntax. It will make the most sense if you are familiar with the formal specification of declarators in the ISO C standard.
Consider (as in C99 subclause 6.7.5 paragraph 4) a declaration T D1
, where T
contains declaration specifiers that specify a type Type (such as int
) and D1
is a declarator that contains an identifier ident. The type specified for ident for derived declarators whose type does not include an attribute specifier is as in the ISO C standard.
If D1
has the form (
attribute-specifier-list D )
, and the declaration T D
specifies the type “derived-declarator-type-list Type” for ident, then T D1
specifies the type “derived-declarator-type-list attribute-specifier-list Type” for ident.
If D1
has the form *
type-qualifier-and-attribute-specifier-list D
, and the declaration T D
specifies the type “derived-declarator-type-list Type” for ident, then T D1
specifies the type “derived-declarator-type-list type-qualifier-and-attribute-specifier-list pointer to Type” for ident.
For example,
void (__attribute__((noreturn)) ****f) (void);
specifies the type “pointer to pointer to pointer to pointer to non-returning function returning void
”. As another example,
char *__attribute__((aligned(8))) *f;
specifies the type “pointer to 8-byte-aligned pointer to char
”. Note again that this does not work with most attributes; for example, the usage of `aligned' and `noreturn' attributes given above is not yet supported.
For compatibility with existing code written for compiler versions that did not implement attributes on nested declarators, some laxity is allowed in the placing of attributes. If an attribute that only applies to types is applied to a declaration, it will be treated as applying to the type of that declaration. If an attribute that only applies to declarations is applied to the type of a declaration, it will be treated as applying to that declaration; and, for compatibility with code placing the attributes immediately before the identifier declared, such an attribute applied to a function return type will be treated as applying to the function type, and such an attribute applied to an array element type will be treated as applying to the array type. If an attribute that only applies to function types is applied to a pointer-to-function type, it will be treated as applying to the pointer target type; if such an attribute is applied to a function return type that is not a pointer-to-function type, it will be treated as applying to the function type.
解读:
1、__attribute__((alias)): 为一个symbol声明一个别名
return-type newname([arguments-list]) __attribute__((alias("oldname")))
oldname: 原函数名 newname: 别名
glibc中 _strong_alias宏的实现
使用示例
#include <stdio.h>
#include <stdlib.h> void foo()
{
printf("\nInside %s\n",__FUNCTION__);
} void _foo() __attribute__((alias("foo"))); //@Author : forest
int main(int args,char ** argv)
{
_foo();
return EXIT_SUCCESS;
}
运行
2、__attribute__((deprecated(MSG))):deprecated,弃用. 如果在源文件在任何地方地方使用deprecated attribute函数,编译器将会发出警告.
使用示例
#include <stdio.h>
#include <stdlib.h> __attribute__((deprecated("foo函数已经被弃用"))) void foo()
{
printf("\nInside %s\n",__FUNCTION__);
} void _foo() __attribute__((alias("foo"))); //@Author : forest
int main(int args,char ** argv)
{
_foo(); foo();
return EXIT_SUCCESS;
}
编译
3、__attribute__(format(archetype,string-index,first-to-check)): format attribute提供了对printf, scanf, strftime, strfmon类型函数参数和对应format类型的检查
__attribute__(format(archetype,string-index,first-to-check)): archtype: 决定format string将会被怎样解释.解释的类型应该是printf, scanf, strftime, gnu_printf, gnu_scanf, gnu_strftime..(也可以像glibc一样使用__printf__,__scanf__,__strftime ...以下划线开始和结尾). string-index: 函数的参数从左到右以此序号为1,2,3递增.string-index就是fmt的序号. first-to-check: 参数列表中第一个和fmt形式比较的参数.
glibc中有很多关于format attribute的使用:
使用示例
#include <stdio.h>
#include <stdlib.h> void foo(const char *fmt,...) \
__attribute__((__format__(__printf__,1,2))); //@Author : forest
int main(int args,char ** argv)
{
//@test
foo("\n%d %d","test_a","test_b"); return EXIT_SUCCESS;
} void foo(const char *fmt,...)
{
/*do nothing*/
}
编译
4、__attribute__((weak)): weak symbol,弱符号. 若存在两个相同的全局符号时,会引发重定义错误. 如果使用weak attribute,则当weak symbol和non-weak symbol同时存在的时候,linker会使用non-weak symbol.若只有weak symbol存在的时候则只使用weak symbol.
Attribute Syntax的更多相关文章
- Web.config Transformation Syntax for Web Application Project Deployment
Web.config Transformation Syntax for Web Application Project Deployment Other Versions Updated: Ma ...
- System Error Codes
很明显,以下的文字来自微软MSDN 链接http://msdn.microsoft.com/en-us/library/windows/desktop/ms681382(v=vs.85).aspx M ...
- 5.24 Declaring Attributes of Functions【转】
转自:https://gcc.gnu.org/onlinedocs/gcc-4.0.0/gcc/Function-Attributes.html 5.24 Declaring Attributes o ...
- Data Binding in WPF
http://msdn.microsoft.com/en-us/magazine/cc163299.aspx#S1 Data Binding in WPF John Papa Code downl ...
- __attribute__ ((__section__ (".init.text")))
在kernel中有很多__init,这个东东到底是何方神圣捏?且听小生我一一道来.下面是其定义:file:/include/linux/init.h 43 #define __init __ ...
- NTSTATUS Values
By combining the NTSTATUS into a single 32-bit numbering space, the following NTSTATUS values are de ...
- Alignment And Compiler Error C2719 字节对齐和编译错误C2719
Compiler Error C2719 'parameter': formal parameter with __declspec(align('#')) won't be aligned The ...
- python模块:logging
# Copyright 2001-2016 by Vinay Sajip. All Rights Reserved. # # Permission to use, copy, modify, and ...
- 初识kbmmw 中的ORM
在kbmmw 5.02.1 中,加入了ORM 的功能(这里可能和其他语言的定义不完全一样),我们就简单的认为 它就是一个类与数据库的转换吧.今天就先介绍一下如何通过kbmmw 的ORM 功能,实现类与 ...
随机推荐
- 3.Java的基本数据类型.md
Java支持的类型分为两类: •基本类型(Primitive Type):boolean和数值类型 ◦整型:byte.short.int.long.char ◦浮点:float.double •nul ...
- Kubernetes1.9 二进制版集群+ipvs+coredns
节点构造如下 : 节点ip 节点角色 hostname 192.168.0.57 node bigdata3 192.168.0.56 node bigdata4 192.16 ...
- linux基本命令练习
1. 熟悉linux命令并且练习用法以及应用场景. 初学者完成Linux系统分区及安装之后,需熟练掌握Linux系统管理必备命令,命令包括:cd.ls.pwd.clear. chmod.chown.c ...
- LisView控件
用LisView控件在窗体中创建一个表,设置一个按钮,点击按钮, 将数据库中的表在这个控件中显示(LisView控件中表格式列名与数据库中一致) 首先使用控件将表的每一列创建好,加入一个按钮,如图,现 ...
- (转载)jenkins 安装 SVN Publisher 后向 svn 提交代码报错: E170001: Authentication required for...
问题描写叙述 安装并启动 jenkins 后,加入了 SVN Publisher 插件,然后在构建任务的“构建后操作”操作中加入了“Publish to Subversion repository”相 ...
- linux下WIFI的AP搜索、连接方法
wpa_supplicant -Dwext -ieth1 -c/etc/wpa_supplicant.conf &wpa_cli save_configwpa_cli reconfigure ...
- 加载 AssetBundle 的四种方法
[加载 AssetBundle 的四种方法] 1.AssetBundle.LoadFromMemoryAsync(byte[] binary, uint crc = 0); 返回AssetBundle ...
- 媒体类型 & 媒体查询
[媒体类型 & 媒体查询] @media 规则允许在相同样式表为不同媒体设置不同的样式. 在下面的例子告诉我们浏览器屏幕上显示一个14像素的Verdana字体样式.但是如果页面打印,将是10个 ...
- html中相对(relative),绝对(absolute)位置以及float的学习和使用案例 (转)
这几天着手于CSS的研究,研究的原因主要是工作需要,最近发现如果做前端仅仅会javascript很难尽善尽美,当然懂样式和html在一定程度上可以让我们更近一步. css较为简单,由于个人擅长编写代码 ...
- Websocket实现群聊、单聊
Websocket 使用的第三方模块:gevent-websocket 群聊 ws群聊.py中的内容 from flask import Flask, request, render_template ...