VLA和操作数大小的副作用

时间:2015-06-24 12:57:36

标签: c sizeof side-effects 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;
}

发生了什么事?

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

1 个答案:

答案 0 :(得分:18)

在发布之前,我似乎应该三思而后行,因为在我做完之后就立刻让我感到震惊。

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

  

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

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

(void)sizeof (g(2), arr);

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

Apparently这种行为在C ++中被改变了,其中逗号运算符不再能够衰减数组。