0

如果以下代码使用 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?

4

1 回答 1

6

因为 g++ 定义了_GNU_SOURCE,这基本上暗示了所有其他功能宏,例如_LARGEFILE_SOURCE. 这些附加宏是在<features.h>包含头文件时定义的,并且大多数系统头文件都包含<features.h>在文件的早期。_GNU_SOURCE对于想要编写可移植 C++ 代码的人来说,预定义的事实一直是令人沮丧的根源。

我相信您可以简单地:

#undef _GNU_SOURCE

但是,这会破坏 libstdc++。哎哟! 多么痛苦!这一切都源于 C++ 中最大的设计缺陷之一,即#include基本上是文本包含的事实。由于大多数 libstdc++ 是在头文件中定义的(不仅仅是声明!),这意味着它们会用_GNU_SOURCE.

如果您需要访问被 隐藏的接口_GNU_SOURCEstrerror_r例如,它完全被 破坏_GNU_SOURCE),那么您只能从不使用任何 libstdc++ 头文件的文件中访问这些接口。

据我所知,这只是 libstdc++ 的一个问题,所以我认为你也可以通过使用 libc++ 或类似的东西来避免这个问题。

于 2016-06-14T23:04:36.373 回答