是否“int size = 10;"?产生一个常量表达式? [英] Does "int size = 10;" yield a constant expression?

查看:42
本文介绍了是否“int size = 10;"?产生一个常量表达式?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

以下代码在 gcc 4.8 和 Clang 3.2 下编译:

The following code compiles under gcc 4.8 and Clang 3.2:

int main()
{
  int size = 10;
  int arr[size];
}

C++ 标准的

8.3.4/1 规定数组的大小必须是一个整数常量表达式,而 size 似乎不是.这是两个编译器中的错误,还是我遗漏了什么?

8.3.4/1 of the C++ Standard says that the size of an array must be an integral constant expression, which size does not seem to be. Is this a bug in both compilers, or am I missing something?

最新的 VC++ CTP 拒绝带有这个有趣消息的代码:

The latest VC++ CTP rejects the code with this interesting message:

error C2466: cannot allocate an array of constant size 0

有趣的部分是它似乎认为 size 为零.但至少它拒绝了代码.gcc 和 Clang 不应该做同样的事情吗?

The interesting part is how it seems to think that size is zero. But at least it rejects the code. Shouldn't gcc and Clang do the same?

推荐答案

这是 可变长度数组VLA 这是一个 C99 功能,但 gccclang 支持它C++ 中的扩展,而 Visual Studio 没有一个>.所以 Visual Studio 在这种情况下遵守标准并且在技术上是正确的.不是说扩展不好,Linux内核依赖很多gcc扩展,因此它们在某些情况下很有用.

This is variable length arrays or VLA which is a C99 feature but gcc and clang support it as an extension in C++ while Visual Studio does not. So Visual Studio is adhering to the standard in this case and is technically correct. Not to say that extensions are bad, the Linux kernel depends on many gcc extensions, so they can be useful in certain contexts.

如果你添加 -pedantic 标志,gccclang 都会警告你,例如 gcc 说(现场观看):

If you add the -pedantic flag both gcc and clang will warn you about this, for example gcc says (see it live):

warning: ISO C++ forbids variable length array 'arr' [-Wvla]
  int arr[size];
              ^

使用 -pedantic-errors 标志会使这成为错误.您可以在这些文档中阅读更多关于扩展的信息 GCC 支持的语言标准clangs 语言兼容性部分.

Using the -pedantic-errors flag will make this an error. You can read more about extensions in these documents Language Standards Supported by GCC and clangs Language Compatibility section.

更新

C++ 标准草案5.19 常量表达式 段落 3 中介绍什么是整数常量表达式,并说:

The draft C++ standard covers what is a integral constant expression in section 5.19 Constant expressions paragraph 3 and says:

整型常量表达式是整型或无作用域枚举类型的表达式,隐式转换为纯右值,其中转换后的表达式是核心常量表达式.[...]

An integral constant expression is an expression of integral or unscoped enumeration type, implicitly converted to a prvalue, where the converted expression is a core constant expression. [...]

阅读本文并不能直观地看出所有可能性,但 Boost 的积分编码指南常量表达式在这方面做得很好.

It is not intuitively obvious from reading this what all the possibilities are but Boost's Coding Guidelines for Integral Constant Expressions does a great job of that .

在这种情况下,由于您使用 const 使用 literal 初始化 size 就足以使其成为 整数常量表达式(见 [expr.const]p2.9.1) 并将代码恢复为标准 C++:

In this case since you are initializing size with a literal using const would suffice to make it an integral constant expression (see [expr.const]p2.9.1) and also bring the code back to being standard C++:

const int size = 10;

使用 constexpr 也可以:

constexpr int size = 10;

阅读 constexpr 之间的差异可能会有所帮助>const.

It would probably help to read Difference between constexpr and const.

参考 C99 标准草案 将是 6.7.5.2 部分 数组声明符 段落 4 上面写着(强调我的):

For reference the equivalent section to 8.3.4 paragraph 1 in the C99 draft standard would be section 6.7.5.2 Array declarators paragraph 4 which says (emphasis mine):

如果大小不存在,则数组类型是不完整类型.如果大小是 * 而不是表达式,则数组类型是未指定大小的可变长度数组类型,只能在具有函数原型范围的声明中使用;124) 这样的数组仍然是完整的类型.如果大小是整数常量表达式并且元素类型具有已知的常量大小,则数组类型不是变长数组类型;否则数组类型为变长数组类型.

If the size is not present, the array type is an incomplete type. If the size is * instead of being an expression, the array type is a variable length array type of unspecified size, which can only be used in declarations with function prototype scope;124) such arrays are nonetheless complete types. If the size is an integer constant expression and the element type has a known constant size, the array type is not a variable length array type; otherwise, the array type is a variable length array type.

这篇关于是否“int size = 10;"?产生一个常量表达式?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆