MSVC 的内联命名空间模拟 (10.0/11.0)

发布于 2024-12-09 08:48:08 字数 890 浏览 0 评论 0原文

有没有办法用 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

但有点违背了目的......

Is there any way to emulate an inline namespace with MSVC?

LLVM's libc++ uses this to create a hidden versioned namespace like so:

#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 {
  }
}

And emulates it on GCC like so:

#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__));
}

Now my question is, how do I achieve the same with MSVC? If it's not possible, I'll be happy with a solution that leaves out the versioning (for now), which I guess would be

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

But kind of defeats the purpose...

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

Saygoodbye 2024-12-16 08:48:08

这种模仿恐怕是不可能的。微软似乎对符号版本控制非常不感兴趣,尽管他们在编译器的每个新版本上都破坏了标准库上的 ABI。 GCC 模拟之所以有效,是因为强使用是内联命名空间功能的基础。微软从来没有类似的东西,所以你不能模拟内联命名空间。恐怕您现在无法对 libc++ 进行版本控制。

微软编译器中的一项功能可能会有所帮助。这是#pragma detector_mismatch:
http://msdn.microsoft.com/en-us/library/ee956429.aspx 一个中央 libc++ 头文件

基本上,您放入

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

中,并且包含该文件的每个模块都会在其中放置一条包含键和值的记录。链接模块时,Microsoft 链接器会检查所有此类记录对于任何给定名称是否具有相同的值,并在出现不匹配时发出警告。

最终结果是,您不能在单个程序中拥有多个并行版本的 libc++,但至少您不会因链接不兼容的对象文件而导致运行时严重崩溃而导致静默损坏。

编辑:忘记提及:这个功能是 VS2010 中的新功能,但是将 libc++ 移植到没有右值引用的编译器可能是毫无希望的。

I'm afraid there is no possibility of such emulation. Microsoft seems to be very uninterested in symbol versioning, even though they break ABI on their standard library on every single new revision of their compiler. The GCC emulation works because strong using was the basis for the inline namespace feature. Microsoft never had a similar thing, so you can't emulate inline namespaces. I'm afraid you're stuck with not versioning libc++ for now.

There is one feature in Microsoft's compiler that may help. This is #pragma detect_mismatch:
http://msdn.microsoft.com/en-us/library/ee956429.aspx

Basically, you put

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

into a central libc++ header file, and every module that includes that file will have a record placed in it that contains the key and value. The Microsoft linker checks, when linking modules, that all such records have the same value for any given name, and complains if there is a mismatch.

The end result is that you can't have multiple parallel versions of libc++ in a single program, but at least you won't get silent corruption from linking incompatible object files that cause nasty crashes at runtime.

Edit: forgot to mention: this feature is new in VS2010, but porting libc++ to a compiler without rvalue refs is probably rather hopeless anyway.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文