Встроенная эмуляция пространства имен для MSVC (10.0 / 11.0) - PullRequest
3 голосов
/ 12 октября 2011

Есть ли способ эмулировать inline namespace с MSVC?

LLVM libc ++ использует это для создания скрытого версионного пространства имен, например:

#define _LIBCPP_BEGIN_NAMESPACE_STD namespace std {inline namespace _LIBCPP_NAMESPACE {
#define _LIBCPP_END_NAMESPACE_STD  } }
#define _VSTD std::_LIBCPP_NAMESPACE
namespace std {
  inline namespace _LIBCPP_NAMESPACE {
  }
}

И эмулирует это в GCC следующим образом:

#define _LIBCPP_BEGIN_NAMESPACE_STD namespace std { namespace _LIBCPP_NAMESPACE {
#define _LIBCPP_END_NAMESPACE_STD  } }
#define _VSTD std::_LIBCPP_NAMESPACE

namespace std {
namespace _LIBCPP_NAMESPACE {
}
using namespace _LIBCPP_NAMESPACE __attribute__((__strong__));
}

Теперь мой вопрос: как мне добиться того же с MSVC? Если это невозможно, я буду доволен решением, которое не учитывает управление версиями (пока), которое, я думаю, будет

#define _LIBCPP_BEGIN_NAMESPACE_STD namespace std {
#define _LIBCPP_END_NAMESPACE_STD }
#define _VSTD std

Но вид побеждает цель ...

1 Ответ

8 голосов
/ 17 октября 2011

Боюсь, нет возможности такой эмуляции.Microsoft, похоже, очень не интересуется версионированием символов, хотя они ломают ABI в своей стандартной библиотеке при каждой новой редакции своего компилятора.Эмуляция GCC работает, потому что сильное использование было основой для встроенной функции пространства имен.У Microsoft никогда не было подобного, поэтому вы не можете эмулировать встроенные пространства имен.Боюсь, вы застряли с не версией libc ++.

В компиляторе Microsoft есть одна особенность, которая может помочь.Это #pragma detect_mismatch: http://msdn.microsoft.com/en-us/library/ee956429.aspx

По сути, вы помещаете

#pragma detect_mismatch("libcxx_version", "1.0")

в центральный заголовочный файл libc ++, и в каждом модуле, включающем этот файл, будет размещена запись, котораясодержит ключ и значение.При компоновке модулей компоновщик Microsoft проверяет, что все такие записи имеют одинаковое значение для любого заданного имени, и жалуется на несоответствие.

Конечный результат заключается в том, что у вас не может быть нескольких параллельных версийlibc ++ в одной программе, но, по крайней мере, вы не получите молчаливого искажения при связывании несовместимых объектных файлов, которые вызывают неприятные сбои во время выполнения.

Редактировать: забыл упомянуть: эта функция является новой в VS2010, но портирует libc ++для компилятора без rvalue refs, вероятно, в любом случае довольно безнадежен.

...