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 无法判断 afoo 中是否定的,我将作为一个问题留给比我更精通编译器胆量的人。