对齐指示符 alignas 和 __attribute__(aligned) 的区别,C++11

14

我目前正在使用C++11开发操作系统内核,但遇到了一个问题,我自己似乎找不到答案。

目前我正在使用编译器特定属性(例如gcc的__attribute__(aligned))来对齐我的分页结构,但我想使用C++11中的alignas指定符代替,在Clang++上这不成问题,因为它欣然接受4096对齐作为参数的alignas,但G++却不行!

首先,alignas指定符和gcc的__attribute__(aligned)之间的主要区别是什么?显然两者都确保将对齐到特定值,但是在gcc中,alignas指定符似乎有一个128的限制,而该属性几乎没有限制,为什么会这样?

还有为什么不能将常量整数传递给alignas指定符?


你使用的是哪个版本的GCC?如果你在这里选择了GCC 4.8:http://liveworkspace.org/code/1hxHGg$0,它可以正常工作。 - R. Martinho Fernandes
2
哦,这是一个类型。听起来把它放在问题中会很有用 :) - R. Martinho Fernandes
@R.MartinhoFernandes:我不知道这会有什么区别。 :) - Skeen
我之前也不知道,但是看到我们的两段代码,似乎确实有所区别。 - R. Martinho Fernandes
显示剩余3条评论
2个回答

7
根据GCC支持状态,对齐支持在gcc 4.7中并不完全支持,但在gcc 4.8中是支持的。从4.8 发布页面可以看到alignas也被列为新支持的特性。
此外,从对齐支持提案(3.11)中也可以看到相关信息:
一个基本对齐方式的表示是小于或等于实现在所有上下文中支持的最大对齐方式,该对齐方式等于alignof(std::max_align_t) (18.1)。
扩展对齐方式由大于alignof(std::max_align_t)的对齐方式表示。是否支持任何扩展对齐方式以及支持它们的上下文是由实现定义的(7.1.6)。具有扩展对齐要求的类型是超对齐类型。
如果常量表达式计算为扩展对齐方式,并且在声明的上下文中实现不支持该对齐方式,则程序是非法的。
__attribute__(aligned)和alignas之间的区别可能并不语义不同,但是一个是编译器扩展,而另一个则完全由标准定义。
回答您的最后一个问题,alignas仅适用于:
alignas ( constant-expression ) 
alignas ( type-id ) 

我知道一个是标准,另一个是编译器扩展,但为什么不能有相同的限制,因为实现显然是相同的呢?此外,不支持作为alignas参数的常量整数的标准是什么? - Skeen
实际上,对于gcc-4.8,它似乎也适用于常量整数。当前的限制可能只是GCC的一个实现问题。我怀疑命名说明符和编译器扩展的实现不同,尽管语义相同。这可能只是一个暂时的限制。 - Thibaut
1
你说得对,看起来它确实有效(是 __attribute__((aligned(...)),它不接受常量整数),我有点希望这是暂时的,或者至少在未来可以在编译器上切换。 - Skeen
你的回答也是为什么它们肯定有不同的实现的原因 :) - Thibaut
我简要查看了gcc 4.8的源代码,发现所有超过std::max_align_t的超对齐类型都会触发此警告。我的猜测是这绝对是一个暂时性问题,并且将在以后实现,因为它不是标准严格定义的。然而,由于行为是实现特定的,警告可能仍然存在。 - Thibaut
显示剩余2条评论

0

它们在可以放置的位置上有所不同。attribute(对齐)可以作为函数的返回类型,但是alignas不能。从语义上讲,它们是相同的。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接