VLA和操作数大小的副作用

Que*_*tin 20 c side-effects sizeof variable-length-array

我知道sizeof永远不会评估它的操作数,除非在所述操作数是VLA的特定情况下.或者,我以为我知道.

void g(int n) {
    printf("g(%d)\n", n);
}

int main(void) {
    int i = 12;

    char arr[i]; // VLA

    (void)sizeof *(g(1), &arr); // Prints "g(1)"
    (void)sizeof (g(2), arr);   // Prints nothing

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

到底是怎么回事?

以防万一,这是在Coliru上用GCC 5.1编译的.

Que*_*tin 18

在发布之前我似乎应该三思而后行,因为在我这样做之后我就立刻想到了.

我对如何sizeof与VLA进行交互的理解实际上是正确的,如下面的引用所证实的那样(感谢@this!):

6.5.3.4 sizeof_Alignof运算符
如果操作数的类型是可变长度数组类型,则计算操作数; 否则,不评估操作数,结果是整数常量

这不是造成这种令人惊讶(对我而言)行为的原因.

(void)sizeof (g(2), arr);
Run Code Online (Sandbox Code Playgroud)

(g(2), arr)子表达式中,逗号运算符触发arr数组到指针的衰减.因此,sizeof操作数不再是VLA,而是一个简单的操作数char*,它回退到不评估其操作数.

显然这种行为在C++中已被改变,其中逗号运算符将不再衰减数组.

  • 这是一次回答你自己的问题的好例子. (2认同)
  • 您可能希望在某处添加:*6.5.3.4 sizeof和_Alignof运算符如果操作数的类型是可变长度数组类型,则计算操作数; 否则,不评估操作数,结果是整数常量.*因此发烧读者会感到困惑. (2认同)