Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

T240730 inline namespace - CppMore #11966

Open
guevara opened this issue Feb 12, 2025 · 0 comments
Open

T240730 inline namespace - CppMore #11966

guevara opened this issue Feb 12, 2025 · 0 comments

Comments

@guevara
Copy link
Owner

guevara commented Feb 12, 2025

T240730 inline namespace - CppMore



https://ift.tt/i9sKfkI



Li Miu


T240725 说到,Unnamed namespaces 有一个唯一的名称会通过 using-directives 自动导入,倘若可以手动指定这个名称,就是 inline namespaces 了。此时,自动导入的名称就是 inline namespace 的名称,比如 std::literalsstd::liternals::chrono_literals实现

正因如此,std/std::literals/std::literals::chrono_literals 任选其一,都可以直接使用时间相关的 Literals。例子:

因此,inline namespaces 最基本的作用就是影响名称查找规则,既可以使用命名空间显式地导入组件,也可以使用隐式的导入行为。但需记住,这并不会像 Unnamed namespaces 那样改变原有的链接方式。

基于这一特性,可控制库 API 版本的向后兼容性。比方说现在库中有一个 S::foo 函数:

在下一版本中,需要修改 S 类的结构,这里假设把 foo() 的名称变成 bar()。只要是公开发布、存在用户群体的库,直接修改自是不成的,那样别人只要稍微升级一下库的版本,旧代码就一片崭红。于是,可以新增加一个 v1 版本的实现:

若是想用旧的,依旧使用 using namespace mylib::v0 即可保证代码兼容。但是,哪个库每次使用还需要手动写明 v0/v1... 啊,用户并不一定清楚库的版本,通常来说,他们只想使用最新的版本。这便是 inline namespaces 的用武之地,改变代码为:

如此一来,只需使用 using namespace mylib,便能静默切到最新的实现版本。若想兼容旧代码,则手动切换为指定的版本即可。

你可能会觉得以下这种方式也能达到同样效果,用不用 inline namespaces 不是必须。

但是,当你尝试在命名空间之外特化 S 时:

就会遇到编译错误,而如果使用 inline namespaces 就不会存在这个错误。

inline namespaces 的另一个作用是控制 ABI 版本,当 ABI 改变时,调用代码和被调用代码的数据内存布局将会变得不一致,这往往会产生 UB。例如:

lib.cpp 编译成共享库,再用 main.cpp 链接该库。

这里正常情况,接着改变一下类的结构,API 保持不变:

重新编译生成链接库,不必重新编译 main.cpp,直接链接输出:

可见,ABI 已经发生了改变,结果变得不可预料,此时最简单的解决办法就是重新编译 main.cpp。但 inline namespaces 可以更好的定位此问题,将新旧代码同样使用 v0/v1 区分版本,ABI 改变时,函数的 Mangled name 将不一致,从而产生链接错误。

具体来讲,将代码变成这样:

再企图将可执行程序链接到新的共享库时,将产生编译期错误:

这样就能够清晰地定位 ABI 问题,要么重新编译程序,要么链接匹配的 ABI 版本。

    </div></div></div></div><br>





via CppMore https://www.cppmore.com

February 12, 2025 at 03:34PM
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant