如何让GCC生成编译过程的中间文件(.i/.s/.o)?gcc 1.c和g++ 1.c有什么区别?gcc 1.c和g++ 1.c预处理有什么区别?
如何让GCC生成编译过程的中间文件(.i/.s/.o)?
可以用--save-temps选项指示GCC生成编译过程中的中间文件。例如:
gcc 1.c --save-temps会生成如下中间文件:
- a-1.i
- a-1.s
- a-1.o
gcc 1.c和g++ 1.c有什么区别?
先假设1.c只有C语言语法,不涉及C++语法,我们利用-E/-S指令对比二者编译过程中的差异。
Based on gcc 11.4.0 and g++ 11.4.0.
#include <stdio.h>
int main()
{
short a = 100;
printf("%d", a);
return 1;
}
- 预处理:差异在头文件包含,g++默认多定义__cplusplus和_GNU_SOURCE,头文件的函数声明会多extern "C"标志,另外打开了GNU更多features.
详细参见:gcc 1.c和g++ 1.c预处理有什么区别? - 编译/汇编/链接:均无差异,参见:gcc 1.c和g++ 1.c编译阶段有什么区别?
_GNU_SOURCE
g++编译比gcc编译,默认会开启_GNU_SOURCE宏,会产生features的差异,这是为什么有时用gcc无法编译过,g++却可以编译过的原因。
/usr/include/features.h当_GNU_SOURCE定义后,打开很多GNU features.
/* If _GNU_SOURCE was defined by the user, turn on all the other features. */
#ifdef _GNU_SOURCE
#undef _ISOC95_SOURCE
#define _ISOC95_SOURCE 1
#undef _ISOC99_SOURCE
#define _ISOC99_SOURCE 1
#undef _ISOC11_SOURCE
#define _ISOC11_SOURCE 1
#undef _ISOC2X_SOURCE
#define _ISOC2X_SOURCE 1
#undef _POSIX_SOURCE
#define _POSIX_SOURCE 1
#undef _POSIX_C_SOURCE
#define _POSIX_C_SOURCE 200809L
#undef _XOPEN_SOURCE
#define _XOPEN_SOURCE 700
#undef _XOPEN_SOURCE_EXTENDED
#define _XOPEN_SOURCE_EXTENDED 1
#undef _LARGEFILE64_SOURCE
#define _LARGEFILE64_SOURCE 1
#undef _DEFAULT_SOURCE
#define _DEFAULT_SOURCE 1
#undef _ATFILE_SOURCE
#define _ATFILE_SOURCE 1
#undef _DYNAMIC_STACK_SIZE_SOURCE
#define _DYNAMIC_STACK_SIZE_SOURCE 1
#endif
一种解法是在.c文件开头#define _GNU_SOURCE强制开启GNU features,或者放在编译选项中。
gcc 1.c和g++ 1.c预处理有什么区别?
借用 gcc 1.c和g++ 1.c有什么区别? 的示例代码,预处理差异在stdio.h预处理后的结果。
- __BEGIN_DECLS在C/C++编译器结果不同,g++会展开成extern “C” {
- g++默认定义了_GNU_SOURCE宏,会开启__USE_GNU, 会包含cookie_io头文件, 也增加了一些特有的函数,例如:
#include <bits/types/cookie_io_functions_t.h>
extern int renameat2 (int __oldfd, const char *__old, int __newfd, const char *__new, unsigned int __flags) noexcept (true); - 如上,_GNU_SOURCE开启了__USE_LARGEFILE64, 定义如下64位类型以及相关函数声明:
typedef __fpos64_t fpos64_t; - __THROW在gcc和g++定义不同, 影响蛮多函数声明:
gcc: __attribute__ ((__nothrow__ , __leaf__))
g++: noexcept (true) - g++有开启__GLIBC_USE (LIB_EXT2),启用了*asprintf函数。
- g++开启__HAVE_FLOAT128, 定义Complex和_Float*相关的类型。
总结一下,g++默认定义__cplusplus和_GNU_SOURCE(间接定义了__USE_GNU, __USE_LARGEFILE64等宏),在预处理头文件上有一些差异,总体而言,并不会改变如上示例代码预处理的总体结构和运行结果。
_GNU_SOURCE是何方神圣? 如何知道g++编译默认会定义_GNU_SOURCE?
若文章对您有帮助,欢迎关注。助您在编程路上越走越好!
微风不燥,阳光正好,你就像风一样经过这里,愿你停留的片刻温暖舒心。
我是程序员小迷(致力于C、C++、Java、Kotlin、Android、iOS、Shell、JavaScript、TypeScript、Python等编程技术的技巧经验分享),若作品对您有帮助,请关注、分享、点赞、收藏、在看、喜欢,您的支持是我们为您提供帮助的最大动力。
原文地址:https://blog.csdn.net/cxsjabcabc/article/details/143655975
免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!