类型和别名之间的"typedef"是否符合标准?

Is "typedef" in between the type and the alias standard-conformant?

本文关键字:标准 是否 typedef 别名 之间 类型      更新时间:2023-10-16

我偶然发现了一些代码,其中 typedef 关键字位于类型和别名之间,如

int typedef INT;

它编译在gcc和clang(实时示例(中。我不太擅长理解标准语言。所以我的问题是:这个标准符合吗?我可以依靠编译器来支持它吗?

typedef 关键字在 C 语言中被归类为存储类说明符,尽管该标准明确指出这是为了方便表达正式语言语法。 尽管如此,typedef可以出现在与任何其他存储类说明符(如 externstatic (完全相同的位置。 [C2011, 6.7.1/5]

实际上,该语法允许存储类说明符与声明中的类型说明符、类型限定符和其他"声明说明符"混合使用。 [C2011, 6.7/1, 6.7/6]

因此,是

的,将 typedef 关键字放在类型名称之后是有效的,如您的示例所示。

TL/DR 版本

是的,int typedef INT符合要求。

詹姆斯·米切纳版本

C

声明语法(C 2011 在线草案(:

6.7 声明

语法

     1 declaration:
        
declaration-specifiers init-declarator-listopt ;        

static_assert-declaration    
declaration-specifiers:        
storage-class-specifier declaration-specifiersopt        
type-specifier declaration-specifiersopt        
type-qualifier declaration-specifiersopt        
function-specifier declaration-specifiersopt         alignment-specifier declaration-specifiersopt
......

这说明在单个声明中,您可以拥有一个或多个声明说明符的序列,其中每个声明说明符可以是存储类说明符(autoexternstatictypedef(,类型说明符(intfloatchar等(,类型限定符(constrestrictvolatile, 等(、函数说明符 ( inline ( 或对齐说明符。

各种说明符出现的顺序无关紧要; static const short int x;可以写成int static short const x,或int short const static x等。 在实践中,大多数人首先放置存储类说明符,然后是任何函数或对齐说明符(如有必要(,然后是任何类型限定符,然后是类型说明符,因此大多数人编写该声明的方式static const short int x

这种语法允许我们编写诸如 long doublelong longunsigned long int 等。

请注意,虽然语法允许任意(和任意长(的类型说明符序列,但有一个语义规则只允许相对较少的类型说明符。 例如,您不能写short short short short xlong long long double y。 仅允许以下序列:

约束

    2 每份声明的声明说明符中应至少给出一个类型说明符,以及每个结构声明和类型名称的说明符限定符列表中。每个列表类型说明符应为以下多集之一(如果存在,则用逗号分隔每个项目有多个多集(;类型说明符可以按任何顺序出现,可能与其他声明说明符混合。
        — void
        — char
        — signed char
        — unsigned char
        — short, signed short, short int, or signed short int
        — unsigned short, or unsigned short int
        — int, signed, or signed int
        — unsigned, or unsigned int
        — long, signed long, long int, or signed long int
        — unsigned long, or unsigned long int
        — long long, signed long long, long long int, or
            
signed long long int        — unsigned long long, or unsigned long long int
        — float
        — double
        — long double
        — _Bool
        — float _Complex
        — double _Complex
        — long double _Complex
        — 原子类型说明符
        — 结构或联合说明符
        — 枚举说明符
        — 类型定义
名称

补遗

正如 Keith 在下面的评论中指出的那样,该语言的未来修订版可能会将存储类说明符限制在声明的开头,因此int typedef INT在未来的编译器下可能不合法。

如果你看一下 7.1/1,你会看到这个语法 decl-specifier: ,这表明 type-specifiertypedef 关键字落在语法中的同一点,允许您像在问题中一样交换它们(尽管作为旁白从不写这样的代码,它根本不是惯用语(。

decl-specifier:

storage-class-specifier
type-specifier
function-specifier
friend
typedef

我使用以下方法编译:

gcc -c -wall -wextra -pedantic -wconversion -std=gnu99

在后台,这意味着-Wold-style-declaration已设置。

然后编译器输出以下警告消息:

warning: 'typedef' is not a beginning of declaration [-Wold-style-declaration]

如果不设置该参数,编译器可以毫无问题地处理语法

因此,发布的语法在标准范围内,但可能会让读者感到困惑。

typedef int INT

正确使用 typedef

的方法

无论您在哪里使用 INT,它都将被 int 数据类型替换

这个主要目的是只将长数据字符串转换为简单值,但在这种情况下,您可以使用普通的 int 本身

您可以仅出于测试目的使用调试进行中继,您可以很好地理解