C++中同名的C结构和C函数
C structure and C function with the same name in C++
当我混合使用 C 和 C++ 代码时,当 Linux C 结构 statx
与 statx()
Linux 系统同名时,我 运行 遇到了问题打电话。
对于安装的 glibc 版本中不存在 statx()
系统调用的情况,我实现了自己的 statx()
版本。我尝试在匿名命名空间中实现替代 statx()
函数,但在这种情况下代码无法编译。
我试图将示例代码简化到最低程度。
#include <iostream>
struct statx {};
namespace {
void statx() { std::cout << "Function statx()\n"; }
}
int main()
{
statx(); // Compile error.
::statx(); // Calling constructor of struct instead of function statx().
}
用g++8编译的输出结果
g++ -std=c++17 -Wall -pedantic -Wextra str_fnc.cpp -o str_fnc
str_fnc.cpp: In function 'int main()':
str_fnc.cpp:13:5: error: reference to 'statx' is ambiguous
13 | statx(); // Compile error.
| ^~~~~
str_fnc.cpp:7:6: note: candidates are: 'void {anonymous}::statx()'
7 | void statx() { std::cout << "Function statx()\n"; }
| ^~~~~
str_fnc.cpp:3:8: note: 'struct statx'
3 | struct statx {};
| ^~~~~
str_fnc.cpp: At global scope:
str_fnc.cpp:7:6: warning: 'void {anonymous}::statx()' defined but not used [-Wunused-function]
7 | void statx() { std::cout << "Function statx()\n"; }
| ^~~~~
当我使用静态函数 statx() 而不是将其包含在匿名命名空间中时,代码编译并成功运行。
#include <iostream>
struct statx {};
static // The replacement anonymous namespace with static function.
void statx() { std::cout << "Function statx()\n"; }
int main()
{
statx();
::statx();
}
谁能解释为什么匿名命名空间中包含 statx() 的示例无法编译且无法运行?
Name hiding [basic.scope.hiding]
2. If a class name ([class.name]) or enumeration name ([dcl.enum]) and a variable, data member, function, or enumerator are declared in the same declarative region (in any order) with the same name (excluding declarations made visible via using-directives ([basic.lookup.unqual])), the class or enumeration name is hidden wherever the variable, data member, function, or enumerator name is visible.
因此在您的第二个示例中,两个名称在同一声明区域中声明,并且该函数隐藏了结构名称。 (您仍然可以通过其详细类型说明符 struct statx
引用该结构)。
在第一个示例中,函数是在不同的声明区域中引入的,因此此规定不适用。相反,正常的命名空间规则生效。也就是说,内部名称就像通过 using 声明一样被带到全局范围。如果在未命名命名空间的内部和外部都声明了相同的名称,则该名称在不合格时会变得不明确。您可以 select 带有 ::
的外部名称,但是无法从未命名的命名空间外部引用内部名称。
当我混合使用 C 和 C++ 代码时,当 Linux C 结构 statx
与 statx()
Linux 系统同名时,我 运行 遇到了问题打电话。
对于安装的 glibc 版本中不存在 statx()
系统调用的情况,我实现了自己的 statx()
版本。我尝试在匿名命名空间中实现替代 statx()
函数,但在这种情况下代码无法编译。
我试图将示例代码简化到最低程度。
#include <iostream>
struct statx {};
namespace {
void statx() { std::cout << "Function statx()\n"; }
}
int main()
{
statx(); // Compile error.
::statx(); // Calling constructor of struct instead of function statx().
}
用g++8编译的输出结果
g++ -std=c++17 -Wall -pedantic -Wextra str_fnc.cpp -o str_fnc
str_fnc.cpp: In function 'int main()':
str_fnc.cpp:13:5: error: reference to 'statx' is ambiguous
13 | statx(); // Compile error.
| ^~~~~
str_fnc.cpp:7:6: note: candidates are: 'void {anonymous}::statx()'
7 | void statx() { std::cout << "Function statx()\n"; }
| ^~~~~
str_fnc.cpp:3:8: note: 'struct statx'
3 | struct statx {};
| ^~~~~
str_fnc.cpp: At global scope:
str_fnc.cpp:7:6: warning: 'void {anonymous}::statx()' defined but not used [-Wunused-function]
7 | void statx() { std::cout << "Function statx()\n"; }
| ^~~~~
当我使用静态函数 statx() 而不是将其包含在匿名命名空间中时,代码编译并成功运行。
#include <iostream>
struct statx {};
static // The replacement anonymous namespace with static function.
void statx() { std::cout << "Function statx()\n"; }
int main()
{
statx();
::statx();
}
谁能解释为什么匿名命名空间中包含 statx() 的示例无法编译且无法运行?
Name hiding [basic.scope.hiding]
2. If a class name ([class.name]) or enumeration name ([dcl.enum]) and a variable, data member, function, or enumerator are declared in the same declarative region (in any order) with the same name (excluding declarations made visible via using-directives ([basic.lookup.unqual])), the class or enumeration name is hidden wherever the variable, data member, function, or enumerator name is visible.
因此在您的第二个示例中,两个名称在同一声明区域中声明,并且该函数隐藏了结构名称。 (您仍然可以通过其详细类型说明符 struct statx
引用该结构)。
在第一个示例中,函数是在不同的声明区域中引入的,因此此规定不适用。相反,正常的命名空间规则生效。也就是说,内部名称就像通过 using 声明一样被带到全局范围。如果在未命名命名空间的内部和外部都声明了相同的名称,则该名称在不合格时会变得不明确。您可以 select 带有 ::
的外部名称,但是无法从未命名的命名空间外部引用内部名称。