为啥 sizeof 表达式不是像 2、4、8 等这样的编译时常量?
Posted
技术标签:
【中文标题】为啥 sizeof 表达式不是像 2、4、8 等这样的编译时常量?【英文标题】:Why is the sizeof expression not a compile-time constant like 2, 4, 8, etc.?为什么 sizeof 表达式不是像 2、4、8 等这样的编译时常量? 【发布时间】:2013-09-12 02:01:32 【问题描述】:我的编译器是最新的 VC++ 2013 预览版。
int main()
__declspec(align(4)) int n1 = 0; // OK.
__declspec(align(sizeof(int))) int n2 = 0; // error C2059: syntax error : 'sizeof'
为什么 sizeof 表达式不是像 2、4、8 等那样的编译时常量?
【问题讨论】:
它说“语法错误”,所以解析器可能需要一个数字常量。在我的 unix 机器上“int a[sizeof(int)];”在全局级别编译正常。__declspec
的东西是 MSVC 特定的扩展语法,它们有一组 nebulous rules,显然,它不受标准规则的约束。从这个意义上说,我认为sizeof()
是否是编译时常量并不重要,因为我认为这些扩展是在编译的其余部分之外处理的(即,介于 MACRO 和适当的 C++ 之间的东西构造)。简而言之,MSVC在这里制定了自己的规则,你只需要忍受它们,如果它不喜欢sizeof()
,那你就不能在那里使用它。
看来 MS 定义了 __alignof
运算符正是为了您想要的目的。对于简单类型,它类似于sizeof
,但对于结构等复杂类型,它的行为有些不同...
AFAICT 甚至 __declspec(align(4u))
也是不允许的。这也是相当稳定的。
【参考方案1】:
而不是问: 为什么 sizeof 表达式不是像 2、4、8 等那样的编译时常量?
(因为实际上,它 是 就像那些示例一样的编译时常量。(:从较新的 C 标准中禁止可变长度数组,它必须是运行时表达式:))
最好问:
为什么align(...)
不接受像 sizeof 表达式这样的编译时间常数?
Microsoft 定义 __declspec(align(#))
只接受一小组值:
见:https://msdn.microsoft.com/en-us/library/83ythb65.aspx
"# 是对齐值。有效条目是从 1 到 8192(字节)的 2 的整数幂,例如 2、4、8、16、32 或 64。"
因此,即使使用简单的常量,也不允许任何值。 __declspec(align(7))
是不允许的,因为它不是 2 的幂。甚至像 __declspec(align(4+4))
这样的简单表达式也是不允许的。
【讨论】:
【参考方案2】:在 C 标准中
sizeof 运算符不应应用于具有 函数类型或不完整类型,到括号中的此类名称 一个类型,或者一个指定位域成员的表达式。这 _Alignof 运算符不得应用于函数类型或不完整类型。
sizeof 运算符产生其操作数的大小(以字节为单位),即 可以是表达式或类型的括号名称。尺寸是 由操作数的类型决定。结果是一个整数。如果 操作数的类型是变长数组类型,操作数 被评估;否则,不计算操作数并且结果 是一个整数常量。
【讨论】:
这对这里有什么帮助?我们甚至不是在谈论 C,而是在谈论 C++,问题来自一些 MSVC 扩展而不是标准。以上是关于为啥 sizeof 表达式不是像 2、4、8 等这样的编译时常量?的主要内容,如果未能解决你的问题,请参考以下文章
为啥c#中bool要占4个字节 32位呢 为啥不用像byte 1个字节存储呢