Почему компилятор принимает неоднозначные определения переменных?

У меня есть такой довольно маленький код:

//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) как неисправный?

Большое спасибо всем!

0

Решение

Второй пример действителен, потому что вы все еще можете получить доступ к глобальному a снаружи этого переводческого подразделения.

a в анонимном пространстве имен содержится определение переменной, имеющей внутреннюю связь. a в глобальном пространстве имен это определение переменной с внешней связью. Вы можете объявить extern int a; в другом блоке перевода и используйте его.

4

Другие решения

Просто потому, что вы не можете сослаться на a в анонимном пространстве имен от main не означает, что код недействителен.

a на анонимное пространство имен все еще можно ссылаться из анонимного пространства имен.

Глобальный a можно ссылаться отовсюду (вам придется использовать ::a в main устранить двусмысленность).

1

Короткий ответ: «потому что в этом нет ничего противозаконного». Это просто с помощью 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;
}
1