为什么这个带有字符数组的代码(被赋予一个变量作为大小)进行编译?
Why does this code with a character array, which was given a variable as size, compile?
玩模板时,我遇到了一个有趣的现象,即数组和定义它的大小,我认为这在C++是不允许的。
我使用了一个全局变量来定义 main() 中数组的大小,并且由于某种原因它起作用(请参阅下面的代码)
1)为什么这甚至编译?我认为只有 constexpr 可用于数组大小
2)假设上述是有效的,它仍然没有解释为什么即使sz = 8明显小于字符串的大小,它仍然有效
3)为什么我们会得到那个奇怪的"@"和"?"。我尝试了不同的字符串组合,例如,只有数字字符("123456789")并且没有出现。
感谢任何帮助。谢谢。
这是我的代码
#include <iostream>
#include <cstring>
using namespace std;
int sz = 8;
int main()
{
const char temp[sz] = "123456abc"; //9 characters + 1 null?
cout << temp << endl;
return 0;
}
输出:
123456AB @
1)为什么这甚至编译?我认为只有 constexpr 可用于数组大小
提问者是正确的,可变长度数组 (VLA) 不是标准C++。g++ 编译器通过扩展包括对 VLA 的支持。这怎么可能?编译器开发人员几乎可以添加任何它想要的东西,只要满足标准要求的行为。由开发人员记录行为。
2)假设上述是有效的,它仍然没有解释为什么即使sz = 8明显小于字符串的大小,它仍然有效
通常,如果使用超过数组大小的值初始化数组,g++ 会发出错误。在这种情况下,我必须通过文档进行确认,以查看C++标准是否需要错误。这似乎是出错的好地方,但我不记得是否需要错误。
在这种情况下,VLA 扩展似乎有一个副作用,可以消除 g++ 通常因尝试过度填充数组而吐出的错误。这很有意义,因为编译器在编译时不知道数组的大小,在一般情况下,无法执行测试。没有测试,没有错误。
C++标准不涵盖这些内容,因为不支持 VLA。
快速浏览一下允许VLA的C标准,并没有为这种情况找到任何指导。C 初始化 VLA 的规则非常简单:你不能。编译器不知道编译时数组的大小,因此无法初始化。字符串文字可能有例外,但我还没有找到。
我也没有在 GCC 文档中找到对行为的良好描述。
clang 根据我对 C 标准的阅读产生了我预期的错误:错误:可变大小的对象可能无法初始化
附录:可能应该先检查堆栈溢出并节省大量时间:初始化可变长度数组。
3)为什么我们会得到那个奇怪的"@"和"?"。我尝试了不同的字符串组合,例如,只有数字字符("123456789")并且没有出现。
似乎正在发生的事情,由于这些都不是标准的,我没有引号来支持它,字符串文字被复制到 VLA 中,最大为 VLA 的大小。VLA 末尾之后的文本部分将被静默丢弃。这包括空终止符,并且在打印未终止的char
数组时未定义行为。
溶液:
尽可能坚持标准化行为。主要编译器可以选择警告您非标准代码。使用 gcc 选项将-pedantic
与编译器一起使用,/permissive-
与最新版本的 Visual Studio 一起使用。当被迫跳出标准时,请查阅编译器文档或实现者本身以获取粘性或未记录的位。
如果你没有得到好的答案,试着找到另一条路。
- 如何创建一个CMake变量,除非显式重写,否则使用默认值
- 用C++中的一个变量定义一个常量
- 有没有什么方法可以使用一个函数中定义的常量变量,也可以由c++中同一程序中的其他函数使用
- 为什么我不能在一个类的不同行中声明和定义成员变量?
- 如何从另一个文件继承私有成员变量和公共函数
- 在 Windows 上,是否可以让 dll 在不使用 PATH 环境变量的情况下在另一个文件夹中查找依赖项?
- 全局变量 多读取器 一个写入器多线程安全?
- 如何声明一个可以在整个程序中使用的全局 2d 3d 4d .. 数组(堆版本)变量?
- 我可以创建一个包含两个变量的 for 循环,但时间复杂度仍然为 O(n) 吗?
- 一个变量的输入值也会保存到另一个变量中
- 从另一个 cpp 文件更改结构内、映射键内的变量
- 在另一个函数 (c++) 中调用变量
- 将双精度变量设置为另一个变量的值
- C++线程安全:如果只有一个线程可以写入非原子变量,但多个线程从中读取. 会遇到问题吗?
- 为什么从另一个构造函数内部调用C++构造函数不修改类变量?
- 如果我注释掉换行符,为什么'string'会成为一个不合格的变量
- 在 C++ 中声明 const 对象需要用户定义的默认构造函数.如果我有一个可变成员变量,为什么不呢?
- 我有一个类,它创建了另一个类的实例.如何将变量通过第一个类传递到第二个类的实例化中?
- C++使用cin给变量一个非整数的值
- 怎么可能有两个同名的变量——一个是全局变量,另一个是局部变量