请考虑以下代码:

#include <stdio.h>
#include <limits.h>
#include <inttypes.h>
#include <stddef.h>

int main(){
    size_t cnt = SIZE_MAX;
    size_t sz = sizeof(long[cnt]);
    printf("%zu\n", sz);
}

6.5.3.4/p2:

如果操作数的类型是可变长度数组类型,则 则计算操作数;否则,不计算该操作数,并且 结果是一个整型常量.

问题是,这种太大的sizeof判断是否定义得很好?由于size_tunsigned,标准保证unsigned整数溢出具有明确定义的行为(与signed不同,在signed中可能会引发实现定义的信号).

我搞不懂的主要问题是

size_t sz = sizeof(long[SIZE_MAX]); //error: size of unnamed array is too large

甚至不编译Godbolt live example

推荐答案

sizeof (long[SIZE_MAX])将不会编译,因为try 形成类型long[SIZE_MAX]违反了约束.摘自C23标准草案的§6.2.5 28:

完整字体的大小应小于或等于SIZE_MAX.

有问题的约束没有列在"Constraints"标题下,因此编译器没有required对此进行诊断.在这种情况下,GCC和Clang都 Select 失败并发出错误消息,但更普遍的是,sizeof (long[SIZE_MAX])具有未定义的行为,因为它违反了显式约束子句之外的"应当".但我认为,当try 声明不受支持的数组时,reasonable个实现将无法编译,并出现类似这样的错误.

这一措辞似乎没有出现在以前的标准中,但标准委员会确定"...that all interpret the current standard that huge objects make the behavior implicitly undefined."委员会认为这一变化不是引入了一种未定义的行为,而是一种澄清,使这一点变得明确.

C++相关问答推荐

单指针和空参数列表之间的函数指针兼容性

__VA_OPT__(,)是否可以检测后面没有任何内容的尾随逗号?

显式地将值转换为它从函数返回的类型的含义是什么?

堆栈在作用域阻塞后会被释放吗?

为什么在函数内部分配内存空间时需要添加符号?

如何跨平台处理UTF-16字符串?

不会停在空格或换行符上的错误

SSH会话出现意外状态

如何在VSCode中创建和使用我自己的C库?

如果格式字符串的内存与printf的一个参数共享,会发生什么情况?

条件跳转或移动取决于未初始化值(S)/未初始化值由堆分配创建(Realloc)

*S=0;正在优化中.可能是GCC 13号虫?或者是一些不明确的行为?

为什么我在我的代码中得到错误和退出代码-1073741819(0xC0000005),但如果我添加了一个不相关的打印语句,它仍然有效?

在我的函数中实现va_arg的问题

C 和 C++ 标准如何告诉您如何处理它们未涵盖的情况?

将指针的地址加载到寄存器内联拇指组件中

当 n 是我们从用户那里获得的整数时,创建 n 个 struct 参数

malloc 属性不带参数

C23 中的 [[reproducible]] 和 [[unsequenced]] 属性是什么?什么时候应该使用它们?

如何让 unlinkat(dir_fd, ".", AT_REMOVEDIR) 工作?