GCC Дефект с анонимными пространствами имен?

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

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? Если кому-то понадобится полный код, я с радостью включу его, но надеюсь, что в свой вопрос я включил достаточно информации, чтобы он мне не понадобился.

1

Решение

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

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

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

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

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

int main() { ... };

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

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

3

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

После некоторых исследований я обнаружил, что анонимные пространства имен в заголовках — плохая идея. Смотрите здесь для возможных решений: Скрытие класса C ++ в заголовке без использования безымянного пространства имен

0

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector