Wal*_*ter 32 c++ alignment c++11 alignas
为了使我的代码标准化并使其更具可移植性,我更换了
#ifdef __GNUC__
typedef __attribute__((aligned(16))) float aligned_block[4];
#else
typedef __declspec(align(16)) float aligned_block[4];
#endif
Run Code Online (Sandbox Code Playgroud)
同
typedef float alignas(16) aligned_block[4];
Run Code Online (Sandbox Code Playgroud)
在C++ 11中.然而,gnu(4.8)并不喜欢这样但是抱怨
test.cc:3:9: warning: attribute ignored [-Wattributes]
typedef float alignas(16) aligned_block[4];
^
test.cc:3:9: note: an attribute that appertains to a type-specifier is ignored
Run Code Online (Sandbox Code Playgroud)
而clang 3.2没有发出警告(即使有-Weverything -Wno-c++98-compat -pedantic).所以我想知道我上面的代码是否正确,更一般地说,我alignas()可以在哪里放置.
编辑(2013年4月):
该标准的相关文章是7.6.2,特别是7.6.2.1
对齐说明符可以应用于变量或类数据成员,但不应该应用于位字段,函数参数,catch子句的形式参数(15.3)或使用注册存储类说明符.对齐说明符也可以应用于类或枚举类型的声明.带省略号的对齐说明符是包扩展(14.5.3).
正如Red XIII已经挖出来的那样.但是,我不够专业,不知道这对我上面的测试意味着什么.
如果clang接受我的属性这一事实意味着什么,那么也许值得一提的是,当试图使用using指令代替a时typedef,clang也会抱怨.此外,与此问题的早期版本中的陈述相反,gcc不仅警告,而且实际上忽略了我对齐的愿望.
Dan*_*rey 28
我认为你只是把它置于alignas错误的位置.如果你直接在标识符之后移动它,GCC和Clang都很满意并应用对齐方式:
typedef float aligned_block alignas(16) [4];
typedef float aligned_block [4] alignas(16);
Run Code Online (Sandbox Code Playgroud)
如果使用的话也是如此using,差异也变得更明显.以下是GCC 不接受的两个版本(警告,对齐忽略):
using aligned_block = float alignas(16)[4];
using aligned_block = float[4] alignas(16);
Run Code Online (Sandbox Code Playgroud)
这是接受的:
using aligned_block alignas(16) = float[4];
Run Code Online (Sandbox Code Playgroud)
我认为海湾合作委员会适用
7.1.3 typedef说明符[dcl.typedef]
2甲typedef的名称也可以通过一个被引入别名声明.的标识符下面的
using关键字成为typedef的名称和可选属性说明符-SEQ继标识符 appertains到的typedef名.它具有与typedef说明符引入的语义相同的语义.[...]
(强调我的)
以上内容非常明确using,规则typedef分为几段,包括§8.3/ 1的末尾,你会发现:
8.3声明者的意义[dcl.meaning]
1 [...]可选的attribute-specifier-seq 跟随声明符id附加到声明的实体.
(再次强调我的)
更新:以上的答案集中在那里的alignas必须放置,而不是它的确切含义.在考虑了一些之后,我仍然认为上述内容应该是有效的.考虑:
7.6.2对齐说明符[dcl.align]
1一种对准说明符可以被应用到一个变量或一类数据成员,但它不应被施加到一个位字段,一个功能参数,一个异常声明(15.3),或一个变量声明的
register存储类符.一个对准说明符还可以(在应用于一类的声明或定义阐述型说明符(7.1.6.3)或类头分别(第9节),)和枚举的声明或定义(分别在opaque-enum-declaration或enum-head中(7.2)).带省略号的对齐说明符是包扩展(14.5.3).
它列出了可以明确应用的情况,并列出了明显无法应用的情况.以上问题的例子都不是.
人们还可以争辩说,由对齐规范创建typedef或using携带的类型别名是别名类型的一部分.此别名可用于创建7.6.2p1允许的变量等,但不能用于创建变量register等.
从这个意义上讲,我认为属性说明符是以延迟的方式应用(在7.6.2的意义上),因此当对齐规范放在语法正确的位置时,OPs示例应该仍然有效.
Ric*_*ith 12
您无法将对齐应用于typedef.在对齐说明符的C++模型中,对齐是类型本身不可分割的一部分,并且a typedef不创建新类型(它只为现有类型提供新名称),因此在中应用对齐说明符没有意义.一个typedef声明.
从[dcl.align](7.6.2)p1:
一个对准说明符可以被应用到一个变量或一类数据成员[...].一个对准说明符还可以(在应用于一类的声明或定义阐述型说明符(7.1.6.3)或类头分别(第9节),)和枚举的声明或定义(分别在opaque-enum-declaration 或enum-head中(7.2)).
这些是标准表示可以应用alignment-specifier(alignas(...))的唯一地方.请注意,这不包括typedef声明或alias-declaration s.
Per [dcl.attr.grammar](7.6.1)p4:
如果属于某个实体或语句的属性说明符 -seq包含不允许应用于该实体或语句的属性,则该程序格式错误.
此措辞旨在应用于属性说明符-seqalignas中可能出现的其他形式的属性,但是当对齐从"真实"属性切换为另一种属性说明符时未正确更新--seq.
所以:你的示例代码使用alignas被认为是病态的.C++标准目前没有明确说明这一点,但它也不允许使用,因此它当前会导致未定义的行为(因为标准没有为它定义任何行为).
草案C++ 11标准http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3337.pdf说明了它(Alignment-speci fi er的形式alignas(赋值表达式)) :
7.6.2对齐指示符[dcl.align]
1对齐指定程序可以应用于变量或类数据成员,但不应用于位字段,函数参数,catch子句的形式参数(15.3)或声明的变量寄存器存储类指定.对齐指定器也可以应用于类或枚举类型的声明.具有省略号的对齐特定是包扩展.
我找到了这个原始提案http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1877.pdf,它说:
alignment-specifier不会成为类型的一部分,但可以创建具有对齐成员变量的类类型.
用这个例子:
// Wrong attempt: Listing 6)
typedef double align_by<0x10000> hwDoubleVector; // Error!
Void clear(hwDoubleVector &toClear, unsigned size);
Run Code Online (Sandbox Code Playgroud)
使用它看起来是违法的typedef.
| 归档时间: |
|
| 查看次数: |
13370 次 |
| 最近记录: |