gpt4 book ai didi

c - 何时以及如何在 sizeof 表达式中评估 VLA?

转载 作者:行者123 更新时间:2023-12-03 23:45:34 31 4
gpt4 key购买 nike

C 标准有这样的语言:

6.5.3.4 The sizeof and _Alignof operators

Semantics

  1. The sizeof operator yields the size (in bytes) of its operand, which may be an expression or the parenthesized name of a type. The size is determined from the type of the operand. The result is an integer. If the type of the operand is a variable length array type, the operand is evaluated; otherwise, the operand is not evaluated and the result is an integer constant.

我不清楚标准是什么意思如果操作数的类型是可变长度数组类型,则计算操作数
  • 如果操作数的类型是变长数组类型,则评估参数似乎没有任何作用,因为大小可以从类型的定义中确定,正如 中所规定的。 6.7.6.2 数组声明符 可变长度数组类型的每个实例的大小在其生命周期内不会改变。
  • 另一方面,如果操作数是可变长度数组类型的括号名称,例如在 sizeof(char[foo()])大小表达式必须在运行时计算才能计算大小,但标准的语言似乎没有涵盖这种情况(类型名称的类型是什么?)

  • 是否应该修改 C 标准的语言以进行澄清?
    这是一个测试程序,用于说明某些特定 VLA 情况下的行为:
    #include <stdio.h>

    static int N = 0;
    int foo(void) { return ++N; }

    int main() {
    typedef char S[foo()]; // foo() is called
    printf("typedef char S[foo()];\t"); printf("N=%d\n", N);
    printf("sizeof(S)=%d\t\t", (int)sizeof(S)); printf("N=%d\n", N);

    typedef char U[foo()]; // foo() is called
    printf("typedef char U[foo()];\t"); printf("N=%d\n", N);
    printf("sizeof(U)=%d\t\t", (int)sizeof(U)); printf("N=%d\n", N);

    S s1;
    printf("S s1;\t\t\t"); printf("N=%d\n", N);
    printf("sizeof(s1)=%d\t\t", (int)sizeof(s1)); printf("N=%d\n", N);

    S s2;
    printf("S s2;\t\t\t"); printf("N=%d\n", N);
    printf("sizeof(s2)=%d\t\t", (int)sizeof(s2)); printf("N=%d\n", N);

    U u1;
    printf("U u1;\t\t\t"); printf("N=%d\n", N);
    printf("sizeof(u1)=%d\t\t", (int)sizeof(u1)); printf("N=%d\n", N);

    U *pu1 = &u1;
    printf("U *pu1 = &u1;\t\t"); printf("N=%d\n", N);
    printf("sizeof(*pu1)=%d\t\t", (int)sizeof(*pu1)); printf("N=%d\n", N);

    U *pu2 = NULL;
    printf("U *pu2 = NULL;\t\t"); printf("N=%d\n", N);
    // sizeof(*pu2) does not evaluate *pu2, contrary to the Standard specification
    printf("sizeof(*pu2)=%d\t\t", (int)sizeof(*pu2)); printf("N=%d\n", N);

    char x2[foo()][foo()]; // foo() is called twice
    printf("char x2[foo()][foo()];\t"); printf("N=%d\n", N);
    printf("sizeof(x2)=%d\t\t", (int)sizeof(x2)); printf("N=%d\n", N);
    printf("sizeof(x2[0])=%d\t\t", (int)sizeof(x2[0])); printf("N=%d\n", N);

    // sizeof(char[foo()]) evaluates foo()
    printf("sizeof(char[foo()])=%d\t", (int)sizeof(char[foo()])); printf("N=%d\n", N);
    return 0;
    }
    输出(clang 和 gcc):
    typedef char S[foo()];  N=1
    sizeof(S)=1 N=1
    typedef char U[foo()]; N=2
    sizeof(U)=2 N=2
    S s1; N=2
    sizeof(s1)=1 N=2
    S s2; N=2
    sizeof(s2)=1 N=2
    U u1; N=2
    sizeof(u1)=2 N=2
    U *pu1 = &u1; N=2
    sizeof(*pu1)=2 N=2
    U *pu2 = NULL; N=2
    sizeof(*pu2)=2 N=2
    char x2[foo()][foo()]; N=4
    sizeof(x2)=12 N=4
    sizeof(x2[0])=4 N=4
    sizeof(char[foo()])=5 N=5

    最佳答案

    每个可变修改的类型都有一个大小,对于每个维度,要么是该维度的倍数,要么独立于它。没有理由评估可变修改对象的大小需要评估任何不会影响对象大小的维度的值,但一些编译器可能会评估这些维度的值,因为可变修改类型的原始规则暗示他们应该被评估。在不同实现以不同方式处理构造的情况下,标准的作者倾向于避免让标准建议任何一种行为更好。因此,标准对涉及可变修改类型的极端情况故意含糊不清,以避免将任何现有实现的行为描述为“错误”或低劣。

    关于c - 何时以及如何在 sizeof 表达式中评估 VLA?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63021254/

    31 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com