#c #gcc #visual-c #typedef
Вопрос:
Учитывая код:
#include <iostream>
typedef int Integer;
Integer Integer = 1234;
int main() {
std::cout << "Integer: " << Integer;
}
Компиляция кода с помощью компилятора gcc 11.2 приведет к ошибкам компиляции:
error: 'Integer Integer' redeclared as different kind of entity
4 | Integer Integer = 1234;
| ^~~~~~~
note: previous declaration 'typedef int Integer'
3 | typedef int Integer;
| ^~~~~~~
In function 'int main()':
error: expected primary-expression before ';' token
7 | std::cout << "Integer: " << Integer;
| ^
Однако изменение кода на:
#include <iostream>
typedef int Integer;
int main() {
Integer Integer = 1234;
std::cout << "Integer: " << Integer;
}
не приведет к ошибке компиляции.
Я попытался использовать компилятор
gcc 11.2,
clang 12.0.1 и MSVC 19.29, и все они потерпели неудачу в первой версии, но разрешили вторую.
Почему вторая версия работает, в то время как первая выходит из строя?
Комментарии:
1. Полностью оставляя в стороне вопрос, является ли это ошибкой компилятора или является ли что-либо из этого допустимым на C : зачем кому-то вообще это нужно? Внутри или вне функции?
2. Я бы никогда не написал ничего подобного. Однако сегодня я столкнулся с этой проблемой в компании, в которой в настоящее время работаю. Кто-то назвал свою переменную так же, как и ее тип, и, хотя она работала в функции, она не была объявлена в глобальной области видимости.
3.
::Integer
отличается от переменной, объявленной и определенной внутриmain
.4. это «буффало буффало буффало..» садовая дорожка, выполненная способом C … только роли предложений в C определяются областями действия.
Ответ №1:
Разница заключается в области охвата.
В первом примере оба Integer
s объявлены в глобальной области:
typedef int Integer;
Integer Integer = 1234;
Во втором примере один объявлен в глобальной области, в то время как другой является локальным для main
:
typedef int Integer;
int main() {
Integer Integer = 1234;
...
}
Это работает, потому что в тот момент , когда компилятор читает первый Integer
внутри main
, существует только одна сущность с таким именем, поэтому она должна ссылаться на тип в глобальной области. Но как только вы объявили переменную с именем Integer
внутри main
, вы не сможете использовать это имя снова для ссылки на тип вместо этого:
typedef int Integer;
int main() {
Integer Integer = 1234; // OK because only the type is visible.
Integer otherInteger = 567; // Error because Integer is a variable here.
::Integer thirdInteger = 89; // OK because :: resolves to the global one.
}