Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/55.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 长度为0的可变长度数组?_C_C99_Language Lawyer_Variable Length Array - Fatal编程技术网

C 长度为0的可变长度数组?

C 长度为0的可变长度数组?,c,c99,language-lawyer,variable-length-array,C,C99,Language Lawyer,Variable Length Array,在C语言中,通常不允许数组的大小为0(除非我使用一个或另一个编译器端扩展) OTOH,有些VLA的长度可能是0 允许吗 我说的是以下代码: void send_stuff() { char data[4 * !!flag1 + 2 * !!flag2]; uint8_t cursor = 0; if (flag1) { // fill 4 bytes of data into &data[cursor] cursor += 4;

在C语言中,通常不允许数组的大小为0(除非我使用一个或另一个编译器端扩展)

OTOH,有些VLA的长度可能是0

允许吗

我说的是以下代码:

void send_stuff()
{
    char data[4 * !!flag1 + 2 * !!flag2];
    uint8_t cursor = 0;
    if (flag1) {
        // fill 4 bytes of data into &data[cursor]
        cursor += 4;
    }
    if (flag2) {
        // fill 2 bytes of data into &data[cursor]
        cursor += 2;
    }
}
结果是一个长度为0、2、4或6的
数据
数组,具体取决于标志的组合


现在的问题是:对于数组长度为0的情况,这是有效的代码吗?

如果我们转到
6.7.5.2
数组声明器第5段说(重点):

如果大小是非整数常量的表达式 表达式:如果它出现在函数原型范围的声明中, 将其视为替换为*;否则,每次都是 评估其值应大于零[…]

事实上,使用
clang
为未定义的行为启用
-fsanize=undefined
标志可以为这种情况生成运行时警告:

运行时错误:可变长度数组绑定的计算结果为非正值0


@AntonH它不适用,因为它是关于结构中的数组,而不是可变长度数组。@AntonH这与此无关。这个问题是关于一个编译器扩展的,它在C99之前是合理的。这个问题是关于可变长度数组的,它只在C99中可用。两者之间没有交叉点。@glglglgl我的错误,读得太快。@pascal cuoq我的错误,读得太快。顺便说一句:建议解决方法:
char data[1+4*!!flag1+2*!!flag2]。当然,这在以后调用
sizeof data
时会遇到问题。在C11:6.7.6.2§5中,它由于添加而移动。刚刚添加的内容供查看较新文档的人参考。@重复数据消除或有趣,但问题被特别标记为
C99
。感谢您的回答。因此,我必须输入类似于
uint8\u t datalen=4*!!flag1+2*!![2];字符数据[datalen?datalen:1]。我想,即使我不访问它,以最初预期的方式声明数组也会产生UB?(因为在给定的情况下,
游标
为0,例如,
memcpy()
将获得要复制的大小0,因此有效地不会发生访问…0长度数组(包括VLA)是有效的扩展名。但必须在首次使用时诊断0长度的常量大小数组,因为它们违反了编译时约束。@GLGL:只需无条件地将数组分配给大于必需的一个元素,可能比仅在“必需”时才尝试分配数组更有效。更好的是,编译器编写者公开声明,任何不愚蠢的编译器都应该能够处理零大小角的情况,而不管标准是否强制要求它。