У меня есть такой довольно маленький код:
//example1
namespace
{
int a;
}
int a;
main()
{
a++;
return 0;
}
Конечно, компилятор g ++ 4.6.1 не может скомпилировать его и выдает ошибку:
./temp.cpp: In function ‘int main()’:
./temp.cpp:10:5: error: reference to ‘a’ is ambiguous
./temp.cpp:6:5: error: candidates are: int a
./temp.cpp:2:9: error: int {anonymous}::a
Все нормально!
Но когда я удаляю ссылку на переменную» в «главный«функция, программа хорошо компилируется:
//example2
namespace
{
int a;
}
int a;
main()
{
return 0;
}
1) Почему компилятор g ++ допускает определение переменной ««, когда в таком случае это запрещает ссылки на него?
2) Это просто функция компилятора g ++, и никакой другой компилятор не может скомпилировать такой код (пример2)?
3) Есть ли у компилятора g ++ соответствующие флаги, чтобы интерпретировать такой код (пример2) как неисправный?
Большое спасибо всем!
Второй пример действителен, потому что вы все еще можете получить доступ к глобальному a
снаружи этого переводческого подразделения.
a
в анонимном пространстве имен содержится определение переменной, имеющей внутреннюю связь. a
в глобальном пространстве имен это определение переменной с внешней связью. Вы можете объявить extern int a;
в другом блоке перевода и используйте его.
Просто потому, что вы не можете сослаться на a
в анонимном пространстве имен от main
не означает, что код недействителен.
a
на анонимное пространство имен все еще можно ссылаться из анонимного пространства имен.
Глобальный a
можно ссылаться отовсюду (вам придется использовать ::a
в main
устранить двусмысленность).
Короткий ответ: «потому что в этом нет ничего противозаконного». Это просто с помощью a
в основном это неправильно. Если вы используете ::a
это даст вам глобальный (без пространства имен).
И вы можете использовать a
внутри самого пространства имен, например мы могли бы иметь функцию:
namespace {
int a;
int work_with_a()
{
a += 2;
return a;
}
}int a;
int main()
{
::a++;
int b = work_with_a();
cout << ::a + b;
}