我在哪里可以在C++ 11中使用alignas()?

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]

2typedef的名称也可以通过一个被引入别名声明.的标识符下面的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-declarationenum-head中(7.2)).带省略号的对齐说明符是包扩展(14.5.3).

它列出了可以明确应用的情况,并列出了明显无法应用的情况.以上问题的例子都不是.

人们还可以争辩说,由对齐规范创建typedefusing携带的类型别名是别名类型的一部分.此别名可用于创建7.6.2p1允许的变量等,但不能用于创建变量register等.

从这个意义上讲,我认为属性说明符是以延迟的方式应用(在7.6.2的意义上),因此当对齐规范放在语法正确的位置时,OPs示例应该仍然有效.

  • 对于typedef和使用clang抱怨的"接受":错误:'alignas'属性仅适用于变量,数据成员和标记类型 (3认同)
  • 这个答案是对的.根据[dcl.align] p1,*alignment-specifier*只能应用于变量,数据成员或类或枚举的声明.这不是那些东西,所以它是不正确的. (3认同)
  • 是的,这是一个问题; GCC的alignment属性没有给你一个新的类型,它给你一个破碎的类型,它有时只会记住它有一个对齐.例如,对齐是[在将类型传递给模板时丢失](http://coliru.stacked-crooked.com/a/9d78ff0834758642). (3认同)

Ric*_*ith 12

您无法将对齐应用于typedef.在对齐说明符的C++模型中,对齐是类型本身不可分割的一部分,并且a typedef不创建新类型(它只为现有类型提供新名称),因此在中应用对齐说明符没有意义.一个typedef声明.

[dcl.align](7.6.2)p1:

一个对准说明符可以被应用到一个变量或一类数据成员[...].一个对准说明符还可以(在应用于一类的声明或定义阐述型说明符(7.1.6.3)或类头分别(第9节),)和枚举的声明或定义(分别在opaque-enum-declarationenum-head中(7.2)).

这些是标准表示可以应用alignment-specifier(alignas(...))的唯一地方.请注意,这包括typedef声明或alias-declaration s.

Per [dcl.attr.grammar](7.6.1)p4:

如果属于某个实体或语句的属性说明 -seq包含不允许应用于该实体或语句的属性,则该程序格式错误.

此措辞旨在应用于属性说明符-seqalignas中可能出现的其他形式的属性,但是当对齐从"真实"属性切换为另一种属性说明符时未正确更新--seq.

所以:你的示例代码使用alignas认为是病态的.C++标准目前没有明确说明这一点,但它也不允许使用,因此它当前会导致未定义的行为(因为标准没有为它定义任何行为).

  • 我仍然不同意您在这里对`typedef`的强调。如果要使用AVX,则必须能够定义一个* type *,它是8个浮点数的数组,对齐到32bytes,或者4个double的数组,对齐方式相同。C ++及其扩展不允许这样做。出现“ typedef”的问题仅是因为需要给该类型起一个短名称,但这并不是对类型进行对齐的应用。 (3认同)

ief*_*rge 7

草案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.

  • 努力+1,但这不是我正在寻找的答案.原提案的文字显然不允许我的建设.但是从2005年开始,这不是标准. (2认同)