2013-04-30 7 views
0

У меня есть такой довольно небольшой код:Почему компилятор принимает определения двусмысленных переменных?

//example1 
namespace 
{ 
    int a; 
} 

int a; 

main() 
{ 
    a++; 
    return 0; 
} 

Конечно, г ++ 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) Почему компилятор г ++ позволяет определять переменная «a», когда в таком случае она запрещает ссылки на нее?

2) Это просто функция компилятора g ++, и никакой другой компилятор не может скомпилировать такой код (пример2)?

3) Имеет ли компилятор g ++ соответствующие флаги для интерпретации такого кода (пример2) как неисправный?

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

ответ

4

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

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

+0

Действительно! :) Я предполагаю, что при использовании такой переменной «a» она должна быть помещена в конец исходного кода ... –

+2

Он должен быть размещен там, где имеет смысл разместить его ... –

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; 
} 
+0

Как использовать «a», переменная из анонимного пространства имен? Является ли это возможным? –

+1

Я отредактировал, чтобы уточнить, как вы можете использовать оба в основном. –

1

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

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

В глобальном a можно ссылаться везде (вам необходимо использовать ::a в main, чтобы устранить двусмысленность).

Смежные вопросы