类型和别名之间的"typedef"是否符合标准?
Is "typedef" in between the type and the alias standard-conformant?
我偶然发现了一些代码,其中 typedef
关键字位于类型和别名之间,如
int typedef INT;
它编译在gcc和clang(实时示例(中。我不太擅长理解标准语言。所以我的问题是:这个标准符合吗?我可以依靠编译器来支持它吗?
typedef
关键字在 C 语言中被归类为存储类说明符,尽管该标准明确指出这是为了方便表达正式语言语法。 尽管如此,typedef
可以出现在与任何其他存储类说明符(如 extern
或 static
(完全相同的位置。 [C2011, 6.7.1/5]
实际上,该语法允许存储类说明符与声明中的类型说明符、类型限定符和其他"声明说明符"混合使用。 [C2011, 6.7/1, 6.7/6]
因此,是的,将 typedef
关键字放在类型名称之后是有效的,如您的示例所示。
TL/DR 版本
是的,int typedef INT
符合要求。
詹姆斯·米切纳版本
C声明语法(C 2011 在线草案(:
6.7 声明
语法
1declaration:
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
......
这说明在单个声明中,您可以拥有一个或多个声明说明符的序列,其中每个声明说明符可以是存储类说明符(auto
,extern
,static
,typedef
(,类型说明符(int
,float
,char
等(,类型限定符(const
,restrict
,volatile
, 等(、函数说明符 ( inline
( 或对齐说明符。
各种说明符出现的顺序无关紧要; static const short int x;
可以写成int static short const x
,或int short const static x
等。 在实践中,大多数人首先放置存储类说明符,然后是任何函数或对齐说明符(如有必要(,然后是任何类型限定符,然后是类型说明符,因此大多数人编写该声明的方式static const short int x
。
这种语法允许我们编写诸如 long double
或 long long
或 unsigned long int
等。
请注意,虽然语法允许任意(和任意长(的类型说明符序列,但有一个语义规则只允许相对较少的类型说明符。 例如,您不能写short short short short x
或long 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-specifier
和 typedef
关键字落在语法中的同一点,允许您像在问题中一样交换它们(尽管作为旁白从不写这样的代码,它根本不是惯用语(。
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 本身
您可以仅出于测试目的使用调试进行中继,您可以很好地理解
- 标准是否使用多余的大括号(例如 T{{{10}}})定义列表初始化?
- 标准是否严格定义了该程序应该如何编译?
- C++标准是否允许<double>在没有开销的情况下实现 std::可选
- 标准是否保证无捕获的 lambda 为空?
- C++:带有大括号初始化列表的函数调用表达式 - 标准是否规定在单个元素列表的微不足道的情况下忽略大括号?
- C++11 标准是否保证零值有符号整数的一元减号为零?
- C++标准:是否有结果对象?
- c++标准是否指定了运算符&&(内置)的求值顺序?
- 该标准是否说明了例外和不同调用约定的共存
- C++标准是否定义了结构中成员函数的函数内定义是否必须具有静态链接?
- 标准是否阻止在可变参数模板中使用足够小的文本值缩小文本转换范围
- C++标准是否包括标准标头必须包含的内容?
- C++标准是否保证 std::string::resize(new_size) 在new_size不大于旧标准时不会导致
- 标准是否定义了共同基础?
- C++标准是否保证失败的插入到关联容器中不会修改 rvalue-reference 参数?
- C++标准是否明确允许/禁止实例化不完整类型的 std::函数?
- 标准是否保证在移动std::p ackaged_task后安全使用std::future?
- C 17标准是否保证工会的地址与其成员的地址相同
- C 标准是否保证统一初始化是例外安全
- C++标准是否允许复制任意多态数据结构?