gcc预处理后可以输出C代码吗?

0md85ypi  于 2023-04-29  发布在  其他
关注(0)|答案(6)|浏览(158)

我使用的是一个开源库,它似乎有很多预处理指令来支持C以外的许多语言。这样我就可以研究库在做什么,我想看看我在预处理后编译的C代码,更像我写的。
gcc(或Linux中常用的任何其他工具)是否可以读取这个库,但输出的C代码可以将预处理转换为任何内容,并且也可以被人类读取?

bvjveswy

bvjveswy1#

是的。将-E选项传递给gcc。这将输出预处理的源代码。

xtupzzrd

xtupzzrd2#

cpp是预处理器。
运行cpp filename.c以输出预处理后的代码,或者更好的方法是将其重定向到一个包含cpp filename.c > filename.preprocessed的文件。

rqdpfwrv

rqdpfwrv3#

-save-temps

-E相比,此选项的优点是可以轻松地将其添加到任何构建脚本中,而不会对构建本身造成太多干扰:

gcc -save-temps -c -o main.o main.c

main.c

#define INC 1

int myfunc(int i) {
    return i + INC;
}

现在,除了正常的输出main.o外,当前工作目录还包含以下文件:

  • main.i是所需的预先拥有的文件,包含:
# 1 "main.c"
# 1 "<built-in>"
# 1 "<command-line>"
# 31 "<command-line>"
# 1 "/usr/include/stdc-predef.h" 1 3 4
# 32 "<command-line>" 2
# 1 "main.c"

int myfunc(int i) {
    return i + 1;
}
  • main.s是一个额外的:-),并包含生成的程序集:
.file   "main.c"
    .text
    .globl  myfunc
    .type   myfunc, @function
myfunc:
.LFB0:
    .cfi_startproc
    pushq   %rbp
    .cfi_def_cfa_offset 16
    .cfi_offset 6, -16
    movq    %rsp, %rbp
    .cfi_def_cfa_register 6
    movl    %edi, -4(%rbp)
    movl    -4(%rbp), %eax
    addl    $1, %eax
    popq    %rbp
    .cfi_def_cfa 7, 8
    ret
    .cfi_endproc
.LFE0:
    .size   myfunc, .-myfunc
    .ident  "GCC: (Ubuntu 8.3.0-6ubuntu1) 8.3.0"
    .section    .note.GNU-stack,"",@progbits

文档: www.example.com

-save-temps=obj

如果要对大量文件执行此操作,请考虑改用:

-save-temps=obj

它将中间文件保存到与-o对象输出相同的目录,而不是当前工作目录,从而避免潜在的基名冲突。
例如:

gcc -save-temps -c -o out/subdir/main.o subdir/main.c

导致创建文件:

out/subdir/main.i
out/subdir/main.o
out/subdir/main.s

很明显,苹果计划接管世界。

-save-temps -v

这个选项的另一个很酷的事情是,如果你添加-v

gcc -save-temps -c -o main.o -v main.c

它实际上显示了在/tmp下使用的显式文件,而不是丑陋的临时文件,因此很容易确切地知道发生了什么,其中包括预处理/编译/汇编步骤:

/usr/lib/gcc/x86_64-linux-gnu/8/cc1 -E -quiet -v -imultiarch x86_64-linux-gnu main.c -mtune=generic -march=x86-64 -fpch-preprocess -fstack-protector-strong -Wformat -Wformat-security -o main.i
/usr/lib/gcc/x86_64-linux-gnu/8/cc1 -fpreprocessed main.i -quiet -dumpbase main.c -mtune=generic -march=x86-64 -auxbase-strip main.o -version -fstack-protector-strong -Wformat -Wformat-security -o main.s
as -v --64 -o main.o main.s

在Ubuntu 19中测试。04(迪斯科丁戈)amd 64,GCC 8.3.0.

CMake预定义目标

CMake自动为预处理文件提供目标:

make help

向我们展示了我们可以做到的:

make main.i

目标运行:

Preprocessing C source to CMakeFiles/main.dir/main.c.i
/usr/bin/cc    -E /home/ciro/bak/hello/main.c > CMakeFiles/main.dir/main.c.i

因此可以在CMakeFiles/main.dir/main.c.i处看到该文件
在cmake 3上测试。16.1.

hgc7kmma

hgc7kmma4#

我使用gcc作为一个预处理器(html文件)。)它做的正是你想要的。它展开“#--”指令,然后输出一个可读的文件。(我尝试过的其他C/HTML预处理器中没有一个这样做--它们连接行,阻塞特殊字符等等。)假设你已经安装了gcc,命令行是:
gcc -E -x c -P -C -traditional-cpp code_before.cpp〉code_after.人民党
(不一定是“cpp”。http://www.cs.tut.fi/~jkorpela/html/cpre.html中有一个关于这种用法的极好描述。
“-traditional-cpp”保留空格和制表符。

u2nhd7ah

u2nhd7ah5#

运行:

gcc -E <file>.c

g++ -E <file>.cpp
7eumitmz

7eumitmz6#

假设我们有一个Message文件。cpp或.c文件

**步骤一:**预处理(参数-E

g++ -E .\Message.cpp > P1

生成的P1文件已扩展宏,头文件内容和注解已剥离。

**第二步:**将预处理文件转换为程序集(参数-S)。这个任务是由编译器完成的

g++ -S .\Message.cpp

生成汇编程序(ASM)(消息。s)。它有所有的汇编代码。

**第三步:**将汇编代码转换为目标代码。注:消息。s在步骤2中生成。

g++ -c .\Message.s

名为Message的对象文件。o生成。它是二进制形式。

**第四步:**链接目标文件。此任务由链接器完成

g++ .\Message.o -o MessageApp

一个exe文件MessageApp。exe在这里生成。

#include <iostream>
using namespace std;

//This a sample program
int main()
{
  cout << "Hello" << endl;
  cout << PQR(P,K) ;
  getchar();
  return 0;
}

相关问题