2015-02-01 2 views
1

У меня есть два заголовочные файлы, которые я в том числе с моей main.cpp, которые имеют следующее определение в анонимном пространстве имен: const string strToken = ("%"); Компиляция с использованием г ++ версии 4.9 результатов в этом:Ошибка GCC с анонимными пространствами имен?

In file included from main.cpp:25:0: 
libraries/trace.h:31:14: error: redefinition of ‘const string {anonymous}::strToken’ 
const string strToken = ("%"); 
      ^
In file included from libraries/debuglogger.h:12:0, 
       from libraries/packet.h:10, 
       from main.cpp:20: 
libraries/strformat.h:23:14: note: ‘const string {anonymous}::strToken’ previously declared here 
const string strToken = ("%"); 
      ^

Я думал, что помещение что-то в анонимном пространстве имен ограничивало его область действия, что делало это проблемой. Я что-то упускаю, или это какой-то дефект в GCC? Если кто-то хочет получить полный код, я бы хотел включить его, но я надеюсь, что включил в свой вопрос достаточную информацию, чтобы не нуждаться в этом.

+0

Почему у вас есть анонимное пространство имен в файле заголовка? В каждой копии будет копия «%». –

+0

@NeilKirk Итак, я собираюсь сделать шаг назад. Допустим, я не хочу ограничивать доступ к этой строке моим заголовочным файлом. Как я могу это сделать, не делая его частным членом класса или использующим анонимное пространство имен? – IanM

+0

Я не уверен в ваших сообщениях, если вы хотите скрыть это от включенных файлов или сделать его доступным. –

ответ

3

Я думал, что положить что-то в анонимном пространстве имен ограничено его в файл прицел

Вы просто откусил. Помещение вещей в анонимное пространство имен ограничивает их видимость для блока перевода . Они переводятся в единое целое, что превращается в один объектный файл, который обычно является одним исходным файлом (файл .cpp) вместе со всем кодом из заголовочные файлы, которые включены в этот исходный файл. Итак, когда у вас есть main.cpp, который включает в себя два заголовка, которые имеют одинаковые объявления (в анонимном пространстве имен или нет), вы получаете сообщение об ошибке.

Всегда думайте о том, что операторы #include являются по существу просто копией содержимого заголовка вместо оператора include. С такими проблемами становится намного легче справиться, как только вы это поймете. Например, ваш частный случай в основном сводится к тому, этому коду после того, как включать-заявление, было решено (копия-вставили в исходном файл):

// from first header: 
namespace { 
    const string strToken = ("%"); 
}; 

// from second header: 
namespace { 
    const string strToken = ("%"); 
}; 

int main() { ... }; 

где ошибка довольно очевидна, и анонимные имена действительно выиграли «Что-то изменить к основной проблеме, что у вас есть несколько определений одной и той же вещи.

Анонимные пространства имен в основном там, чтобы вы могли создавать вещи внутри единицы перевода (обычно в самом файле .cpp), без каких-либо следов из них после компиляции единицы перевода в объектный файл. Вы можете найти this tutorial полезной для понимания всего процесса компиляции и компоновки.

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