typedef(指向)VLA 是否需要计算大小表达式?

问题描述 投票:0回答:1

typedef VLA 是否需要计算大小表达式?

int f(void);
int main(void)
{
    typedef int (T) [ f() ];       // is f required to be evaluated ?
    T x;
    return sizeof x;
}

typedef 指向 VLA 的指针是否需要计算大小表达式?

int f(void);
int main(void)
{
    typedef int (*T) [ f() ];      // is f required to be evaluated ?
    T x;
    return sizeof x;
}

UPD。在

f
的定义中是可见的,那么对它的调用可能会被优化掉:

int f(void)
{
    return 4;
}

int main(void)
{
    typedef int (*T) [ f() ];
    return sizeof(T);
}

生成的代码(GCC 和 LLVM):

main:
        mov     eax, 8
        ret

这是预期的,因为没有真正需要调用

f
来确定指针的大小。

c language-lawyer declaration typedef variable-length-array
1个回答
7
投票

根据 C 标准(§6.7.8 类型定义

3 在存储类说明符为 typedef 的声明中,每个 声明符将标识符定义为 typedef 名称,表示 按照 6.7.6 中描述的方式为标识符指定类型。 任意 与可变长度数组关联的数组大小表达式 每次声明 typedef 时都会评估声明符 name 按照执行顺序到达。

C 标准中有一个例子

8 示例 5 如果 typedef 名称表示可变长度数组类型, 数组的长度在 typedef 名称是固定的 定义,而不是每次使用时:

void copyt(int n)
{
    typedef int B[n]; // B is n ints, n evaluated now
    n += 1;
    B a; // a is n ints, n without += 1
    int b[n]; // a and b are different sizes
    for (int i = 1; i < n; i++)
        a[i-1] = b[i];
}

这是一个演示程序。

#include <stdio.h>

int f( void )
{
    static int n;
    
    return ++n;
}

void g( void )
{
    typedef int ( *T )[ f() ];
    
    T p;
    
    printf( "sizeof( *p ) = %zu\n", sizeof( *p ) );
}

int main(void) 
{
    for ( size_t i = 0; i < 10; i++ )
    {
        g();
    }
}

程序输出为

sizeof( *p ) = 4
sizeof( *p ) = 8
sizeof( *p ) = 12
sizeof( *p ) = 16
sizeof( *p ) = 20
sizeof( *p ) = 24
sizeof( *p ) = 28
sizeof( *p ) = 32
sizeof( *p ) = 36
sizeof( *p ) = 40
© www.soinside.com 2019 - 2024. All rights reserved.