【问题标题】: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)) 也是不允许的。这也是相当稳定的。

标签: c++ c visual-c++ sizeof compile-time-constant


【解决方案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 扩展而不是标准。
    猜你喜欢
    • 2010-12-31
    • 2019-11-13
    • 1970-01-01
    • 1970-01-01
    • 2015-11-03
    • 2013-10-16
    • 2014-08-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多