GCC与Clang对C++20模块中非导出using namespace作用域的处理合规性疑问
C++20模块中未导出
using namespace的标准行为疑问 在C20模块接口文件中添加未导出的using namespace指令后,Clang 16.0.6会让该指令作用于独立的模块实现文件,但GCC 13.2.1不会。现需确认哪种处理符合当前C标准,以及该差异是否属于实现定义特性。
复现代码
library.h
#ifndef RAG_DOLL_h #define RAG_DOLL_h namespace rag { class Doll {}; }; #endif
interface.ixx
export module xd; import <library.h>; using namespace rag;
implementation.cxx
module xd; import <library.h>; Doll kore;
编译结果
- GCC编译时触发错误:
implementation.cxx:5:1: error: 'Doll' does not name a type 5 | Doll kore; | ^~~~
将代码改为rag::Doll kore;可修复该错误。
- Clang无需修改即可正常编译。
编译脚本
gcc.sh
#!/bin/sh export LANG=C prg="`realpath "$0"`" && cd "`dirname "$prg"`" || exit $? ln -sf interface.ixx interface.cxx \ && g++ -c -fmodules-ts -I. -fmodule-header library.h \ && g++ -c -fmodules-ts -I. interface.cxx -o interface.o \ && g++ -c -fmodules-ts -I. implementation.cxx -o implementation.o rm -rf gcm.cache interface.cxx
clang.sh
#!/bin/sh export LANG=C prg="`realpath "$0"`" && cd "`dirname "$prg"`" || exit $? ln -sf interface.ixx interface.cxxm \ && clang++ -std=c++20 -I. -fmodule-header library.h -o library.pcm \ && clang++ -std=c++20 -I. --precompile interface.cxxm -fmodule-file=library.pcm -o interface.pcm \ && clang++ -std=c++20 -I. -c implementation.cxx -fmodule-file=library.pcm -fmodule-file=xd=interface.pcm -o implementation.o rm -f library.pcm interface.cxxm
标准行为说明
GCC的处理符合C++20标准,Clang的行为属于编译器扩展。
根据C++20模块规则:
- 模块接口单元中的未导出声明(包括
using namespace指令)属于模块的私有作用域,仅对该接口单元自身可见,不会被同模块的其他翻译单元(比如独立的实现单元)继承。 - 模块实现单元是独立的翻译单元,它和接口单元共享模块的命名空间,但接口单元中未导出的声明不会进入实现单元的作用域。
因此,在implementation.cxx中,必须显式使用rag::Doll来访问类型,而不能依赖接口单元中的using namespace rag;——该指令仅在interface.ixx内部有效。
内容的提问来源于stack exchange,提问作者Morgana
相关产品推荐
相关产品推荐

