为什么在用 g++ 而不是 gcc 编译时 _LARGEFILE_SOURCE 定义在 stdio.h 中?
Why is _LARGEFILE_SOURCE defined in stdio.h when compiling with g++ but not gcc?
如果以下代码是用 gcc lfs.c -o lfs 编译的,它不会打印任何内容。但是,如果它是用 g++ lfs.c -o lfs 编译的,它会打印“_LARGEFILE_SOURCE defined by stdio.h!”。
#ifdef _LARGEFILE_SOURCE
int largefile_defined_at_start = 1;
#else
int largefile_defined_at_start = 0;
#endif
// This defines _LARGEFILE_SOURCE, but only in C++!
#include <stdio.h>
int main(void) {
#ifdef _LARGEFILE_SOURCE
if (!largefile_defined_at_start)
printf("_LARGEFILE_SOURCE defined by stdio.h!");
#endif
return 0;
}
无论哪种情况,编译器都没有定义 _LARGEFILE_SOURCE:
gcc -dM -E - < /dev/null |grep _LARGEFILE_SOURCE |wc -l
0
g++ -dM -E - < /dev/null |grep _LARGEFILE_SOURCE |wc -l
0
为什么在通过 g++ 前端调用 GCC 时 stdio.h 定义 _LARGEFILE_SOURCE?
因为g++定义了_GNU_SOURCE
,这基本上隐含了所有其他特征宏,比如_LARGEFILE_SOURCE
。这些额外的宏是在包含 <features.h>
header 时定义的,并且大多数系统 header 文件在文件的最前面包含 <features.h>
。 _GNU_SOURCE
是预定义的这一事实一直让想要编写可移植 C++ 代码的人感到沮丧。
我相信你可以简单地:
#undef _GNU_SOURCE
但是,这会破坏 libstdc++。哎哟!多么痛苦!这一切都源于 C++ 中最大的设计缺陷之一,即 #include
基本上是文本包含这一事实。由于大多数 libstdc++ 都是在 header 文件中定义的(不仅仅是声明!),这意味着它们会用 _GNU_SOURCE
.
污染您的程序
如果你需要访问被_GNU_SOURCE
隐藏的接口(例如strerror_r
,被_GNU_SOURCE
完全破坏)那么你只能从不使用任何 libstdc++ headers.
的文件
据我所知,这只是 libstdc++ 的一个问题,所以我认为您也可以通过使用 libc++ 或其他类似的东西来避免这个问题。
如果以下代码是用 gcc lfs.c -o lfs 编译的,它不会打印任何内容。但是,如果它是用 g++ lfs.c -o lfs 编译的,它会打印“_LARGEFILE_SOURCE defined by stdio.h!”。
#ifdef _LARGEFILE_SOURCE
int largefile_defined_at_start = 1;
#else
int largefile_defined_at_start = 0;
#endif
// This defines _LARGEFILE_SOURCE, but only in C++!
#include <stdio.h>
int main(void) {
#ifdef _LARGEFILE_SOURCE
if (!largefile_defined_at_start)
printf("_LARGEFILE_SOURCE defined by stdio.h!");
#endif
return 0;
}
无论哪种情况,编译器都没有定义 _LARGEFILE_SOURCE:
gcc -dM -E - < /dev/null |grep _LARGEFILE_SOURCE |wc -l
0
g++ -dM -E - < /dev/null |grep _LARGEFILE_SOURCE |wc -l
0
为什么在通过 g++ 前端调用 GCC 时 stdio.h 定义 _LARGEFILE_SOURCE?
因为g++定义了_GNU_SOURCE
,这基本上隐含了所有其他特征宏,比如_LARGEFILE_SOURCE
。这些额外的宏是在包含 <features.h>
header 时定义的,并且大多数系统 header 文件在文件的最前面包含 <features.h>
。 _GNU_SOURCE
是预定义的这一事实一直让想要编写可移植 C++ 代码的人感到沮丧。
我相信你可以简单地:
#undef _GNU_SOURCE
但是,这会破坏 libstdc++。哎哟!多么痛苦!这一切都源于 C++ 中最大的设计缺陷之一,即 #include
基本上是文本包含这一事实。由于大多数 libstdc++ 都是在 header 文件中定义的(不仅仅是声明!),这意味着它们会用 _GNU_SOURCE
.
如果你需要访问被_GNU_SOURCE
隐藏的接口(例如strerror_r
,被_GNU_SOURCE
完全破坏)那么你只能从不使用任何 libstdc++ headers.
据我所知,这只是 libstdc++ 的一个问题,所以我认为您也可以通过使用 libc++ 或其他类似的东西来避免这个问题。