C++ 全局命名空间编译问题
c++ global namespace compile problems
我正在使用一个特定的工具链(BlackBerry Playbook NDK附带的工具链)。我认为它基于 GCC 4.4.2。当我尝试使用此工具链编译某些库时,我遇到了我认为是 c++ 全局命名空间的奇怪问题。例如,我会收到如下错误:
'::sprintf' has not been declared
在链接到GNU c ++标准库时,我从未收到这些错误。但是,Playbook NDK 默认使用 Dinkumware C++ libs,我总是必须遍历每个错误,并且通常会添加 C 等效项(在本例中为 stdio.h)。由于我无法控制的原因,我无法链接到GNU c++标准库,它没有表现出任何这些问题。
如果我尝试编译一个更大的项目,我可能会收到数百个这样的错误。是否有不涉及编辑源的解决方法?在上面的例子中,文件通常包含"cstdio"作为标头,但它在"std"命名空间下声明了sprintf。所以我唯一的选择是包含 C 标头或添加 std 命名空间。
,C++标准要求在标准库中声明的所有符号(包括<c....>
标头中的 C 库)都可以在 std::
命名空间中访问。它并不禁止它们也出现在全局命名空间中,并且出于向后兼容性的原因,C++标准库的某些实现(如libstdc++)选择让它们出现。
您有几种可能性:
- 您可以继续直接包含 C 标头(如
<stdio.h>
),但通常不鼓励这样做,因为它们可能C++意识不足,并且可能会产生冲突 (1) - 您可以为每个调用添加前缀,尽管这可能不切实际
- 您可以选择您使用的符号:
using std::printf;
文件顶部或每个函数中 - 你可以直截了当地放一个
using namespace std;
指令。但是你会拉很多东西...
我个人的建议是在调用前面加上前缀,或者挑选最常用的函数并将它们导入全局或当前命名空间中。
在迁移方面,一种直截了当的可能性是实际"包装"标准标头:
// cstdio.hpp
#include <cstdio>
#if defined(_DIRKUMWARE_) // note: you'll have to research the symbol to check
namespace yournamespace {
using std::printf;
using std::vptrinf;
} // namespace yournamespace
#endif // defined(_DIRKUMWARE_)
然后让一个脚本将代码库中所有出现的<stdio.h>
和<cstdio>
替换为<cstdio.hpp>
(显然,除了在这个文件中)。这样,您可以针对标准库的每个实现调整此文件,而不是在包含这些函数的每个文件中重复变通方法。
注(1):C标准没有规定功能是由函数还是宏提供。通常,min
和max
可能是宏。C++标准规定了功能,这就是为什么使用 C++ 标头通常更安全的原因。
基本上你被困在一个角落里。
根据C++标准:
包括
cstdio
将std
命名空间中的符号名称导入,也可能在全局命名空间中导入符号名称。
和
包括
stdio.h
导入全局命名空间中的符号名称,也可能导入 std 命名空间中的符号名称。
因此,如果在包括 cstdio
的特定实现中没有导入全局命名空间中的符号,那么您唯一的选择是对 std
命名空间使用完全限定名称。
这是因为该行为由C++标准明确定义,只是不太为人所知。
如果源包含的几个常见头文件,则可以使用所需的包含内容修改这些文件。
GCC 有一个名为 -include
的命令行选项,允许您在编译源文件的其余部分之前强制源文件包含文件。您可以修改 Makefile 或项目构建脚本的等效项,以为您执行包含。
// c_includes.h
#include <stdio.h>
#include <stdlib.h>
//...
g++ -include c_includes.h ...
- 编译包含字符串的代码时遇到问题
- 在编译C++代码(具有dlib和opencv)到WASM时面临问题
- 编译要在英特尔Hyperscan中使用的.cc文件时出现问题
- 如何在 Mac 上正确编译C++,当它在 Linux 上编译没有问题时?
- Rextester 语言编译C++问题
- 这是使用回溯的 nqueen 问题,但我使用了动态 2d 数组,我的程序编译良好,但不返回任何输出
- 编译 llvm 插件时出现问题:llvm/Config/llvm-config.h:没有这样的文件或目录
- C++ 多级虚拟继承编译问题
- 编译问题:在函数"_start"中:未定义对"主"的引用 collect2:错误:ld 返回 1 个退出状态
- 在Linux上使用Clang / OLLVM交叉编译helloworld Windows可执行文件时的问题
- 使用 CImg 库的 std::min 和 std::max 的编译问题
- Qt Visual Studio 2015 加载项编译问题
- 构造函数和 G++ 编译配方的问题
- 解析问题 - 预期的非限定 ID - #include <array> 编译错误
- libssh 问题编译问题未定义的错误
- Eclipse 问题 - 编译期间不考虑 .c 和 .cpp 文件中定义的预处理
- Visual Studio 2017问题编译了C 代码,而该代码则在Linux中编译
- 这个C++代码有什么问题?编译错误:调用“测试::测试(测试)”没有匹配函数
- 试图编译基本Boost PropertyTree示例时出现问题-编译错误.该怎么做
- 如何解决***缺少分隔符的问题.编译QT(或支持库)时