在 C++ 命名空间中包含 C 标头 - 这是标准行为吗?
Including C headers in a C++ namespace - is it a standard behavior?
我一直认为C头文件必须包含在C++程序的顶层。 无论如何,我意外地发现C++允许在子命名空间中包含 C 标头。
namespace AAA {
extern "C" {
#include "sqlite3.h" // C API.
}
}
然后,所有 C 类型和函数都将放置在命名空间中。更有趣的是,所有链接的C函数也都在工作!我还发现这可能会导致一些预处理器问题,但除此之外,它似乎工作得很好。
这是标准行为吗?(我正在使用Clang 3.x)如果是,此功能的名称是什么,在哪里可以找到标准中提到的此功能?
你甚至可能会做一些奇怪的事情,比如
//test.c
int
#include "main.h"
{
return 1;
}
//main.h
main(void)
在执行任何语法检查之前,将展开预处理器宏。上面的例子将扩展到
int
main(void)
{
return 1;
}
这是法典。虽然您确实应该避免使用此类示例,但在某些情况下,包含在另一个元素中非常有用。在您的问题中,这取决于在编译过程中名称是如何被篡改的。如果头文件中的所有定义都使用extern "C"
声明,则名称将在目标文件中未被搜索,但是,如果包含实现的对象文件不使用与它在消费代码中的定义相同的命名空间并且未将其声明为extern "C"
,则情况并非如此。
这是标准行为吗?
是的 - 该行为受标准支持,因为C++编译器实际上没有代码是"C"与"C++"的概念,除非extern "C"
用于抑制命名空间重整。
不禁止重整的结果是,如果您尝试与定义标题中提到的行外符号(extern
变量、函数)的 C 库链接,则可能会在链接时出现"未解决的符号"错误。
如果是[标准功能],此功能的名称是什么,在哪里可以找到标准中提到的此功能?
这只是#include
工作方式的结果,在 16.2 源文件包含 [cpp.include] 中定义,至关重要的是:
[
#include
] 导致该指令被由 " 分隔符之间的指定序列标识的源文件的全部内容替换。
因此,无论"C"标头发生什么,都与头文件的顶部和底部存在周围的namespace
/extern
语句和大括号完全相同......当编译的下一阶段开始时,源代码的确切来源无关紧要(除了显示与源文件正确相关的错误消息)。
- 重载运算符 + 用于向量:命名空间标准
- 如何为缺少预定义运算符而不扩展命名空间"std"的标准类型定义运算符>> (istream &, ...)?
- 如何在不使用命名空间标准的情况下取消设置ios::fixed
- 我可以停止 GCC 将标准库名称包含在全局命名空间中吗?
- 关于"使用命名空间标准"的问题?
- 从另一个命名空间访问标准命名空间数据成员
- 在全局命名空间中重载不依赖于用户定义类型的标准定义类型的运算符是否格式正确?
- 正在使用命名空间标准;必需的
- 强制标准名称空间的命名空间范围
- fabsf 是 C++11 中标准命名空间的一部分吗?
- C++命名空间std的定义方式/位置(文档/标准链接)
- ABS并使用命名空间性标准
- 使用从较新的C++标准向后移植的类型和模板扩展命名空间 std
- C 标准:DO命名空间constexpr变量具有内部链接
- C++在全局命名空间中找不到非标准 C 函数
- 在 C++ 命名空间中包含 C 标头 - 这是标准行为吗?
- 在命名空间中放入一个标准的纯C头#include指令可以吗
- 是否“使用命名空间标准::p花边持有人”不符合要求
- 解决方案与命名空间/ADL 事物的标准一致性
- 使用头文件而不是标准命名空间