Недавно я наткнулся на странную конструкцию кода, которая приводит компиляторы C в странное состояние. Я хотел бы получить объяснение, почему это происходит.
Вот мой небольшой фрагмент кода, который демонстрирует проблему:
#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
тем фактом, что l-значение оператора type_t
'=' ошибочно считается умножением между type_t
и type_c
. Поскольку type_c
неизвестен, это объясняет сообщение об ошибке.
Но почему у нас такая путаница с l-значением? type_t
не должно быть однозначно, что type_t
ссылается на тип, а не на переменную?
Я предполагаю, что это не проблема реализации, так как gcc
и clang
ведут себя одинаково. Но мне бы очень хотелось иметь ключ к этой проблеме.