C ++中数组索引的奇怪类型分配
Weird type assignment for array index in C++
嗨,我有一个示例程序
#include <iostream>
int main() {
int a = -5;
int arr[a];
std::cout << "Size of arr: " << sizeof(arr) << std::endl;
return 0;
}
我在这里得到 17179869164 的输出。
我的问题是数组大小值不应该接受负值!如果我尝试给出 [-5],它会抛出一个错误。但现在我如何获得 17179869164 的输出。
我也有我的假设,-5 被转换为无符号整数值 4294967291,总大小为 17179869164 = 4294967291 * 4(整数大小)。
所以我想知道为什么编译器将 signed int 类型转换为 unsigned int 而不是抛出编译时错误。我需要清楚地了解编译器是如何执行那段代码的?
这就是所谓的未定义行为。要捕获此类错误,您可以使用静态分析器的帮助。
其他人在这里问了类似的问题:
Declaring an array of negative length
对于 C++,标准不提供可变长度数组,但可能由编译器扩展提供。对于 C,简短的回答是标准将值转换为正整数值,除非它是常量表达式——在您的情况下导致使用无符号值(使用二进制补码值作为正值)。具体来说:
C11 Standard - 6.7.6.2 Array
declarators(p5)
If the size is an expression that is not an integer constant
expression: if it occurs in a declaration at function prototype scope,
it is treated as if it were replaced by *; otherwise, each time it is
evaluated it shall have a value greater than zero.
我注意到 GodBolt 中有一些有趣的行为。
我拿了你的代码并添加了第二个副本,其中 a
声明为常量:
#include <iostream>
int foo() {
int a = -5;
int arr[a];
std::cout << "Size of arr: " << sizeof(arr) << std::endl;
return 0;
}
int bar() {
const int a = -5;
int arr[a];
std::cout << "Size of arr: " << sizeof(arr) << std::endl;
return 0;
}
Then I threw GCC, Clang, and MSVC at them.
据我所知,GCC 和 Clang 都支持可变长度数组 (VLA) 作为 "extra feature",而且他们都毫无怨言地吃了 foo
。而不支持 VLA 的 MSVC 抱怨道。
另一方面,none 接受了 bar
因为 a
是负面的。
至于为什么 GCC 和 Clang 无法判断 a
在 foo
中是否定的,我将作为一个问题留给比我更精通编译器胆量的人。
嗨,我有一个示例程序
#include <iostream>
int main() {
int a = -5;
int arr[a];
std::cout << "Size of arr: " << sizeof(arr) << std::endl;
return 0;
}
我在这里得到 17179869164 的输出。
我的问题是数组大小值不应该接受负值!如果我尝试给出 [-5],它会抛出一个错误。但现在我如何获得 17179869164 的输出。
我也有我的假设,-5 被转换为无符号整数值 4294967291,总大小为 17179869164 = 4294967291 * 4(整数大小)。
所以我想知道为什么编译器将 signed int 类型转换为 unsigned int 而不是抛出编译时错误。我需要清楚地了解编译器是如何执行那段代码的?
这就是所谓的未定义行为。要捕获此类错误,您可以使用静态分析器的帮助。
其他人在这里问了类似的问题: Declaring an array of negative length
对于 C++,标准不提供可变长度数组,但可能由编译器扩展提供。对于 C,简短的回答是标准将值转换为正整数值,除非它是常量表达式——在您的情况下导致使用无符号值(使用二进制补码值作为正值)。具体来说:
C11 Standard - 6.7.6.2 Array declarators(p5)
If the size is an expression that is not an integer constant expression: if it occurs in a declaration at function prototype scope, it is treated as if it were replaced by *; otherwise, each time it is evaluated it shall have a value greater than zero.
我注意到 GodBolt 中有一些有趣的行为。
我拿了你的代码并添加了第二个副本,其中 a
声明为常量:
#include <iostream>
int foo() {
int a = -5;
int arr[a];
std::cout << "Size of arr: " << sizeof(arr) << std::endl;
return 0;
}
int bar() {
const int a = -5;
int arr[a];
std::cout << "Size of arr: " << sizeof(arr) << std::endl;
return 0;
}
Then I threw GCC, Clang, and MSVC at them.
据我所知,GCC 和 Clang 都支持可变长度数组 (VLA) 作为 "extra feature",而且他们都毫无怨言地吃了 foo
。而不支持 VLA 的 MSVC 抱怨道。
另一方面,none 接受了 bar
因为 a
是负面的。
至于为什么 GCC 和 Clang 无法判断 a
在 foo
中是否定的,我将作为一个问题留给比我更精通编译器胆量的人。