【发布时间】:2018-11-27 20:23:28
【问题描述】:
我最近偶然发现了一个奇怪的代码结构,它导致 C 编译器进入一个奇怪的状态。我想解释一下为什么会发生。
这是我演示问题的小代码sn-p:
#include <stdlib.h>
typedef int type_t;
int main (void)
{
int a = 10, b = 100;
type_t *type_t = &a; // We name a variable with type name
type_t *type_c = &b; // We define a variable with type_t
return EXIT_SUCCESS;
}
这是gcc显示的错误信息:
#> gcc -Wall -Wextra -o sample sample.c
sample.c: In function ‘main’:
sample.c:11:11: error: ‘type_c’ undeclared (first use in this function); did you mean ‘type_t’?
type_t *type_c = &b;
^~~~~~
type_t
sample.c:11:11: note: each undeclared identifier is reported only once for each function it appears in
或者,clang:
#> clang -Wall -Wextra -o sample sample.c
sample.c:11:11: error: use of undeclared identifier 'type_c'; did you mean 'type_t'?
type_t *type_c = &b;
^~~~~~
type_t
sample.c:10:11: note: 'type_t' declared here
type_t *type_t = &a;
^
sample.c:11:10: error: invalid operands to binary expression ('type_t *' (aka 'int *') and 'type_t *')
type_t *type_c = &b;
~~~~~~ ^~~~~~~
2 errors generated.
请注意,如果我们修改代码如下,它可以正常编译:
int main (void)
{
int a = 10, b = 100;
type_t *type_c = &b; // We define a variable with type_t
type_t *type_t = &a; // We name a variable with type name
return EXIT_SUCCESS;
}
那么,我现在的问题!
似乎错误是由于赋值运算符“=”的左值被误认为是type_t 和type_c 之间的乘积而产生的。由于type_c 未知,它解释了错误信息。
但是,为什么我们对左值有这种困惑? type_t 指的是类型而不是变量,这不是很明确吗?
我想这不是实现问题,因为gcc 和clang 的行为相同。但是,我真的很想知道这个问题的关键。
【问题讨论】:
-
确认 MSVC 2017 也重现此行为
-
MSVC 2008 抱怨 ... 错误 C2377: 'type_t' : redefinition; typedef 不能用任何其他符号重载....参见“type_t”的声明 ....错误 C2065:“type_c”:未声明的标识符
-
所以,它一定是 C 标准的一部分……但是,为什么???