标准库标题层次结构

时间:2014-01-11 19:55:45

标签: c++ gcc include

跟进我对这个问题的回答:SIGSEGV on declaration

在这个问题中,提问者在一些简单的代码上遇到了分段错误的问题。事实证明它甚至没有为我和其他人编译。由于重新声明名为bsearch的变量,GCC(4.8.1)发出错误,该变量恰好与std中的函数名称相同。这导致了冲突,因为代码也使用using namespace std;。由于提问者接受了我的回答,我猜这与运行时错误有某种关系(虽然很奇怪)。

然而,提问者说代码会在代码块上编译得很好,其他人证实了这一点。 bsearch应在cstdlib中定义,但代码中不包含该内容。

事实证明,如果包含cstdlib,gcc会包含iostream,正如人们从追踪中可以看到的那样:

g++ -O0 -g3 -Wall -c -fmessage-length=0 -std=c++0x -Wall -Wextra -pedantic -MMD -MP -MF"src/Test.d" -MT"src/Test.d" -o "src/Test.o" "../src/Test.cpp"
../src/Test.cpp:14:27: error: ‘long long int bsearch’ redeclared as different kind of symbol
      long long int bsiter,bsearch;
                           ^
In file included from /usr/lib/gcc/x86_64-pc-linux-gnu/4.8.1/include/g++-v4/cstdlib:72:0,
                 from /usr/lib/gcc/x86_64-pc-linux-gnu/4.8.1/include/g++-v4/ext/string_conversions.h:41,
                 from /usr/lib/gcc/x86_64-pc-linux-gnu/4.8.1/include/g++-v4/bits/basic_string.h:2815,
                 from /usr/lib/gcc/x86_64-pc-linux-gnu/4.8.1/include/g++-v4/string:52,
                 from /usr/lib/gcc/x86_64-pc-linux-gnu/4.8.1/include/g++-v4/bits/locale_classes.h:40,
src/subdir.mk:18: recipe for target 'src/Test.o' failed
                 from /usr/lib/gcc/x86_64-pc-linux-gnu/4.8.1/include/g++-v4/bits/ios_base.h:41,
                 from /usr/lib/gcc/x86_64-pc-linux-gnu/4.8.1/include/g++-v4/ios:42,
                 from /usr/lib/gcc/x86_64-pc-linux-gnu/4.8.1/include/g++-v4/ostream:38,
                 from /usr/lib/gcc/x86_64-pc-linux-gnu/4.8.1/include/g++-v4/iostream:39,
                 from ../src/Test.cpp:1:
/usr/include/stdlib.h:754:14: error: previous declaration of ‘void* bsearch(const void*, const void*, size_t, size_t, __compar_fn_t)’
 extern void *bsearch (const void *__key, const void *__base,
              ^
make: *** [src/Test.o] Error 1

仅在c ++ 0x和c ++ 11模式下才这样做。

这个结构是否包含c ++标准中的必需,允许或定义?在cplusplus.com上,我发现iostream将包含ostreamios,但没有关于包含更多内容的信息。

1 个答案:

答案 0 :(得分:2)

C ++标准规定在某些地方必须包含另一个标头(例如,<iostream>必须包含<istream><ostream>)。否则,该标准允许包含标题并使声明可用,这些声明不需要从特定标题中获得。

我认为拥有一个标头系统会很有用,这些标头可以准确地提供那些可用的声明,但我不知道它是否可用。这些标头可能没有实际定义,只能用于验证是否包含所有必需的标头。将标题作为实际实现的一部分可能会更好,但这会使声明变得更复杂。