在那里我可以在C ++ 11使用alignas()在那、里我、alignas

由网友(阁楼)分享简介:在为了规范我的code,使之更便于携带,我换成In an effort to standardize my code and make it more portable, I replaced#ifdef __GNUC__typedef __attribute__((aligned(16))) float ali...

在为了规范我的code,使之更便于携带,我换成

In an effort to standardize my code and make it more portable, I replaced

#ifdef __GNUC__
typedef __attribute__((aligned(16))) float aligned_block[4];
#else
typedef __declspec(align(16)) float aligned_block[4];
#endif

typedef float alignas(16) aligned_block[4];

在C ++ 11。然而,GNU(4.8)不喜欢这一点,但抱怨

in C++11. However, gnu (4.8) doesn't like that but complains

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

而铿锵3.2创建无警告(甚至 -Weverything -Wno-C ++ 98-compat的-pedantic )。 所以我想我的code以上是否是正确的,更普遍,其中 alignas(),不能放置。

whereas clang 3.2 creates no warning (even with -Weverything -Wno-c++98-compat -pedantic). So I wonder whether my code above is correct and, more generally, where alignas() can and cannot be placed.

-------------编辑--------------

-------------edit--------------

与标准相关的文章是7.6.2,特别是7.6.2.1

The relevant article from the standard is 7.6.2, in particular 7.6.2.1

这是对准说明符可以被应用到一个变量或一类数据成员,但它不应被施加到一个位字段,一个功能参数,的catch子句(15.3)的形式参数,或变量使用寄存器存储说明符进行声明。对准说明符也可被应用到类或枚举类型的声明。一个对齐说明符以省略号是一个扩展包(14.5.3)。

An alignment-specifier may be applied to a variable or to a class data member, but it shall not be applied to a bit-field, a function parameter, the formal parameter of a catch clause (15.3), or a variable declared with the register storage class specifier. An alignment-specifier may also be applied to the declaration of a class or enumeration type. An alignment-specifier with an ellipsis is a pack expansion (14.5.3).

为已经挖出了由红十三。不过,我不是专家,足以知道这是什么意思了我上面的测试。

as already dug out by Red XIII. However, I'm not expert enough to know what this means for my test above.

如果说铛接受我的属性的事实意味着什么,那或许值得一提的是,尝试使用,而不是的typedef ,铛也抱怨。此外,相对于这一问题早期版本的说法,GCC不只是发出警告,但确实是忽略了我的愿望一致。

If the fact that clang accepts my attribute means anything, it's perhaps worth mentioning that when trying to use a using directive instead of a typedef, clang also complains. Also, contrary to a statement in an earlier version of this question, gcc does not only warn, but indeed ignores my wish for alignment.

推荐答案

我觉得你刚才放置的 alignas 在错误的位置。如果将它直接的在的标识符,GCC和Clang的是快乐和应用的对齐方式:

I think you just placed the alignas in the wrong position. If you move it directly after the identifier, both GCC and Clang are happy and apply the alignment:

typedef float aligned_block alignas(16) [4];
typedef float aligned_block [4] alignas(16);

这也是如此,如果你使用使用,其中的差别也变得更加明显。这里有两个版本是的不是的海湾合作​​委员会(警告,对准忽略)受理:

this is also true if you use using, where the difference also becomes more apparent. Here are two versions that are not accepted by GCC (warning, alignment ignored):

using aligned_block = float alignas(16)[4];
using aligned_block = float[4] alignas(16);

和这里的接受之一:

using aligned_block alignas(16) = float[4];

我认为,海湾合作委员会适用

I think that GCC applies

2 A 的typedef名的,也可以通过的别名声明引入的。在标识符的继使用关键字变成的的typedef名的和在可选的属性说明-SEQ 的继的代码的 appertains到的的typedef名的。它,就好像它是由`的typedef符引入相同的语义。 [...]

7.1.3 The typedef specifier [dcl.typedef]

2 A typedef-name can also be introduced by an alias-declaration. The identifier following the using keyword becomes a typedef-name and the optional attribute-specifier-seq following the identifier appertains to that typedef-name. It has the same semantics as if it were introduced by the `typedef specifier. [...]

(重点煤矿)

以上是相当明确的使用的typedef 有s $ P $通过几个段落垫规则包括在§8.3/ 1,在这里你找到结束:

The above is quite clear for using, the rules for typedef are spread through several paragraphs, including at the end of §8.3/1, where you find:

1 [...]可选的属性 - 符-SEQ 的下面一个的声明符-ID 的 appertains该声明的实体。

8.3 Meaning of declarators

是时候展示我的独门绝技了

1 [...] The optional attribute-specifier-seq following a declarator-id appertains to the entity that is declared.

(再次,重点煤矿)