Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/144.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 在C++;11?_C++_C++11_Alignment_Alignas - Fatal编程技术网

C++ 在C++;11?

C++ 在C++;11?,c++,c++11,alignment,alignas,C++,C++11,Alignment,Alignas,为了使我的代码标准化并使其更具可移植性,我将 #ifdef __GNUC__ typedef __attribute__((aligned(16))) float aligned_block[4]; #else typedef __declspec(align(16)) float aligned_block[4]; #endif 与 在C++11中。然而,gnu(4.8)不喜欢这一点,但抱怨 test.cc:3:9: warning: attribute ignored [-Wattribu

为了使我的代码标准化并使其更具可移植性,我将

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

在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
而Clang3.2不会产生任何警告(即使使用
-Weverything-Wno-c++98 compat-pedantic
)。 因此,我想知道我上面的代码是否正确,更一般地说,哪里可以放置
alignas()

编辑(2013年4月)

本标准的相关条款为7.6.2,特别是7.6.2.1

对齐说明符可以应用于变量或类数据成员,但不能应用于位字段、函数参数、catch子句(15.3)的形式参数或用寄存器存储类说明符声明的变量。对齐说明符也可以应用于类或枚举类型的声明。带有省略号的对齐说明符是块扩展(14.5.3)

已经被红十三挖出来了。然而,我还不够专业,不知道这对我的上述测试意味着什么

如果clang接受我的属性这一事实意味着什么,那么可能值得一提的是,当试图使用
using
指令而不是
typedef
时,clang也会抱怨。此外,与此问题的早期版本中的声明相反,gcc不仅发出警告,而且确实忽略了我的对齐愿望。

C++11标准草案对此进行了说明(对齐规范的形式为
alignas
(赋值表达式)):

7.6.2校准规范[dcl.校准]

1校准规范可应用于变量或类数据成员,但不得应用 对于位字段,函数参数、catch子句(15.3)的形式参数或声明的变量 使用寄存器存储类规范。线形规范也可应用于路线声明 类或枚举类型。带有省略号的对齐规范是一个包扩展

我找到了这个原始提案,上面写着:

对齐说明符不会成为类型的一部分,但可以创建类类型 使用对齐的成员变量

在这个例子中:

// Wrong attempt: Listing 6)
typedef double align_by<0x10000> hwDoubleVector; // Error!
Void clear(hwDoubleVector &toClear, unsigned size);
//错误的尝试:清单6)
typedef通过hwdublevector进行双对齐;//错误!
无效清除(HWDubleVector&toClear,无符号大小);
将其与
typedef
一起使用似乎是非法的,请尝试:

typedef float alignas(16) aligned_block[4];

我想您刚刚把
对齐设置为
放错位置了。如果将其直接移动到标识符之后,GCC和Clang都会很高兴并应用对齐方式:

typedef float aligned_block alignas(16) [4];
typedef float aligned_block [4] alignas(16);
如果您使用
使用
,也会出现这种情况,其中的差异也会变得更加明显。以下是GCC不接受的两个版本(警告,忽略对齐):

这是公认的一个:

using aligned_block alignas(16) = float[4];
我认为GCC适用

7.1.3类型定义说明符[dcl.typedef] 2还可以通过别名声明引入typedef名称。
using
关键字后面的标识符成为typedef名称,标识符后面的可选属性说明符seq属于该typedef名称。它的语义与由
typedef
说明符引入的语义相同。[……]

(强调矿山)

上述内容对于使用的
非常清楚,
typedef
的规则分布在多个段落中,包括§8.3/1末尾,您可以在其中找到:

8.3声明人的含义【dcl.含义】 1[…]声明器id后面的可选属性说明符seq与声明的实体相关

(再次强调我的)


更新:上述答案集中在必须放置
对齐的位置,而不是其确切含义。再想一想,我仍然认为上面的说法应该是正确的。考虑:

7.6.2对齐说明符[dcl.align] 1对齐说明符可以应用于变量或类数据成员,但不能应用于位字段、函数参数、异常声明(15.3)或使用
寄存器
存储类说明符声明的变量。对齐说明符也可以应用于类的声明或定义(分别在详细的类型说明符(7.1.6.3)或类头(第9条)中)和枚举的声明或定义(分别在不透明的枚举声明或枚举头(7.2)中)。带有省略号的对齐说明符是块扩展(14.5.3)

它列出了可以明确应用的情况,也列出了无法明确应用的情况。上述问题的例子两者都不是

也有人可能认为,由
typedef
使用
创建的类型别名将对齐规范作为别名类型的一部分。此别名可用于创建7.6.2p1所允许的变量等,但不能创建带有
寄存器的变量等


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

您不能将对齐应用到
typedef
。在对齐模式的C++模型中,对齐是类型本身的不可分割的部分,而 TyPulf不创建新类型(它只为现有类型提供新名称),因此在“<代码> TyPosif< /Cord>Nealth.< /P>中应用对齐说明符是没有意义的”。 从[dcl.align](7.6.2)p1开始:

对齐说明符可以应用于变量或类数据成员[…]。对齐说明符也可应用于类的声明或定义(在详细的类型说明符(7.1.6.3)或类头(第
using aligned_block = float alignas(16)[4];
using aligned_block = float[4] alignas(16);
using aligned_block alignas(16) = float[4];