Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/152.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++全局命名空间编译问题_C++_Global Namespace - Fatal编程技术网

C++全局命名空间编译问题

C++全局命名空间编译问题,c++,global-namespace,C++,Global Namespace,我正在使用一个特定的工具链,即黑莓Playbook NDK附带的工具链。我认为它基于GCC4.4.2。当我尝试用这个工具链编译某些库时,我遇到了一些奇怪的问题,我认为是C++全局命名空间的东西。例如,我将得到如下错误: '::sprintf' has not been declared 我从不在链接到GNU C++标准库时得到这些错误。然而,PrasBooNDK默认使用DunCuMudioC++ LIBS,我总是必须检查每个错误,并且通常在C的情况下添加C等效STDIO。出于我无法控制的原因,

我正在使用一个特定的工具链,即黑莓Playbook NDK附带的工具链。我认为它基于GCC4.4.2。当我尝试用这个工具链编译某些库时,我遇到了一些奇怪的问题,我认为是C++全局命名空间的东西。例如,我将得到如下错误:

'::sprintf' has not been declared
<>我从不在链接到GNU C++标准库时得到这些错误。然而,PrasBooNDK默认使用DunCuMudioC++ LIBS,我总是必须检查每个错误,并且通常在C的情况下添加C等效STDIO。出于我无法控制的原因,我不能链接到GNU C++标准库,它没有显示任何这些问题。p>
如果我试图编译一个更大的项目,我可能会遇到数百个这样的错误。是否有不涉及编辑源代码的变通方法?在上面的示例中,该文件通常将cstdio作为头文件,但它在“std”名称空间下声明了sprintf。因此,我唯一的选择是包含C头或添加std名称空间。

基本上,你被困在一个角落里

<>按C++标准:

包含cstdio将在std命名空间中导入符号名称,可能还会在全局命名空间中导入

包含stdio.h将在全局名称空间中导入符号名称,也可能在std名称空间中导入

因此,如果在包括cstdio的特定实现中没有导入全局名称空间中的符号,那么您唯一的选择就是为std名称空间使用完全限定的名称。
这是因为行为被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 ...

如果源文件包含一些常见的头文件,则只需修改包含所需内容的头文件即可

GCC有一个名为-include的命令行选项,允许您在编译源文件的其余部分之前强制源文件包含一个文件。您可以修改Makefile或项目构建脚本的等效文件,以便为您执行包含操作

// c_includes.h
#include <stdio.h>
#include <stdlib.h>
//...

g++ -include c_includes.h ...

<>实际上,C++标准规定在标准库中声明的所有符号,其中包括头部中的C库,可以在STD::No.Stof中访问。它不禁止它们出现在全局命名空间中,并且C++标准库的一些实现,如LIbSTDC++ ++,选择了它们以向后兼容性的原因存在。 您有几种可能性:

你可以继续直接包含C头,但是它通常被劝阻,因为它们可能不是C++感知的,可能会产生冲突1。 您可以为每个调用添加前缀,尽管这可能不切实际 您可以选择使用的符号:使用std::printf;在文件顶部或每个函数内 您可以直截了当地使用名称空间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_)
然后让脚本将代码库中所有出现的和替换为该文件中的“分开”。通过这种方式,您可以针对标准库的每个实现调整此文件,而不是在包含这些函数的每个文件中重复解决方法


注1:C标准不要求功能由函数或宏提供。通常,最小值和最大值可能是宏。C++标准规定了函数,这就是为什么使用C++头通常更安全。

< P>实际上,C++标准规定在标准库中声明的所有符号,其中包括在标题中的C库,在STD::命名空间中是可访问的。它不禁止它们出现在全局命名空间中,并且C++标准库的一些实现,如LIbSTDC++ ++,选择了它们以向后兼容性的原因存在。 你有 e有几种可能性:

你可以继续直接包含C头,但是它通常被劝阻,因为它们可能不是C++感知的,可能会产生冲突1。 您可以为每个调用添加前缀,尽管这可能不切实际 您可以选择使用的符号:使用std::printf;在文件顶部或每个函数内 您可以直截了当地使用名称空间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_)
然后让脚本将代码库中所有出现的和替换为该文件中的“分开”。通过这种方式,您可以针对标准库的每个实现调整此文件,而不是在包含这些函数的每个文件中重复解决方法


注1:C标准不要求功能由函数或宏提供。通常,最小值和最大值可能是宏。C++标准规定了函数,这就是为什么使用C++头通常更安全。< /P>你不应该添加STDIO.H抱歉,我编辑了我的帖子来反映发生了什么。源文件通常包括cstdio。但是它会抛出一个错误,除非我在std名称空间下添加函数调用。他的问题是在std名称空间下声明所有内容。他习惯于绕开这一点,想知道是否还有其他办法。除了使用std作为前缀或使用namespace std;之外,我认为没有;。使用GNU STL并不能解决这个问题,但对我来说确实如此。明确地说,我正试图使用这个特定的工具链来移植项目。如果我尝试用我的桌面机器编译相同的项目,我不会有任何问题,它只会工作。但是同一个项目不会使用工具链编译。另外,如果我强制工具链使用g++驱动程序而不是默认的qcc驱动程序,那么一切都可以正常编译。两者之间的区别在于,qcc驱动程序链接与Dinkumware libs,g++链接与GNU stl。我不知道这两种方法之间还有什么区别。你应该添加not stdio.hSorry,我编辑了我的帖子来反映发生了什么。源文件通常包括cstdio。但是它会抛出一个错误,除非我在std名称空间下添加函数调用。他的问题是在std名称空间下声明所有内容。他习惯于绕开这一点,想知道是否还有其他办法。除了使用std作为前缀或使用namespace std;之外,我认为没有;。使用GNU STL并不能解决这个问题,但对我来说确实如此。明确地说,我正试图使用这个特定的工具链来移植项目。如果我尝试用我的桌面机器编译相同的项目,我不会有任何问题,它只会工作。但是同一个项目不会使用工具链编译。另外,如果我强制工具链使用g++驱动程序而不是默认的qcc驱动程序,那么一切都可以正常编译。两者之间的区别在于,qcc驱动程序链接与Dinkumware libs,g++链接与GNU stl。我不知道这两种方法之间还有什么区别。