你能把你的代码直接传递到gcc吗?例如:gcc-?'int main(){return 0;}'

Cle*_*der 3 gcc compilation g++ system command-line-arguments

你能把你的代码直接传递到gcc吗?如果是的话,它的命令行选项是什么?

例如:

g++ -? 'int main(){return 0;}'
Run Code Online (Sandbox Code Playgroud)

我需要知道,因为我正在使用系统命令,并且我不想创建文件:

system("g++ -C "+code_string+" -o run.out");
Run Code Online (Sandbox Code Playgroud)

Basile Starynkevitch 解决方案有效,但是当我使用换行符时出现编译错误:

echo '#include\nint main(){printf("Hello World"); return 0;}' | g++ -x c++ -Wall -o myprog /dev/stdin
Run Code Online (Sandbox Code Playgroud)

编辑:修复了它

echo -e '#include\nint main(){printf("Hello World"); return 0;}' | g++ -x c++ -Wall -o myprog /dev/stdin
Run Code Online (Sandbox Code Playgroud)

Bas*_*tch 5

您可以要求 GCC 从 stdin 读取。阅读其文档的调用 GCC章节。将其-x选项/dev/stdin或 with 一起使用-

 echo 'int main(){return 0;}' | g++ -x c++ -O -Wall -o myprog /dev/stdin
Run Code Online (Sandbox Code Playgroud)

顺便说一句,因为int main(){return 0;}是一个有效的 C 程序,你可以使用

 echo 'int main(){return 0;}' | gcc -x c -O -Wall -o myprog -
Run Code Online (Sandbox Code Playgroud)

从编程上来说,您应该考虑使用popen(3)来获取pipeline(7)的某个FILE*句柄(因此然后检查它是否为空),然后最后将其放入其中。不要忘记测试 的状态。FILE* f = popen("g++ -x c++ -O -Wall -o myprog /dev/stdin", "w");ffprintfpclosepclose

然而,GCC 大部分时间都花在了解析上(使用-ftime-report 开发者选项来了解)。您经常希望要求它进行优化(使用-O2 -march=native或 仅-O作为示例),并且您肯定希望要求所有警告(至少使用-Wall或 也可以-Wextra)。

如果您想从一些发出的 C++ 代码中生成一些插件代码以在 Linux 上动态加载,请将其编译为与位置无关的代码共享对象动态库中,例如/tmp/someplugin.so/tmp/myemitted.cc

g++ -o /tmp/someplugin.so -fPIC -shared -Wall -O /tmp/myemitted.cc
Run Code Online (Sandbox Code Playgroud)

等等...然后使用dlopen(3)dlsym(3)/tmp/someplugin.so来获取一些加载的符号。我的GCC MELT正在做这个。

由于解析时间可以忽略不计,您可以在一些临时文件中写入 C 或 C++ 代码(在大多数 Linux 系统上/tmp/通常/run是一些快速的tmpfs,因此写入它不需要磁盘 I/O)。

最后,最近的GCC(至少使用GCC 6)也有GCCJIT(实际上是libgccjit)。您可以使用它来构建生成代码的某种表示形式,然后要求 GCC 对其进行编译。

另请参见这个那个。阅读C++ dlopen mini howtoProgram Library HowTo以及 Drepper 的How To Write Shared Libraries

我宁愿不制作文件

生成一个临时文件(参见mkstemp(3)等...,您实际上也可以在以/tmp/结尾的情况下通用一些随机文件名,然后使用atexit(3)传递一些执行unlink(2).c ...的函数来注册其删除)是非常快(但您应该在从中发出 C++ 或 C 代码之前在内存中构建某种AST )。使用某些命令来编译生成的代码的优点是(对于高级用户)能够更改编译器或选项(通过编辑来配置)。MakefilemakeMakefilemake

因此,恕我直言,您在避免临时文件方面是错误的(请注意,gcc&g++也在生成和删除临时文件,例如包含一些汇编代码)。相反,我建议/tmp/mytemp*.cc使用一些随机数生成一个临时文件(匹配)(请参阅random(3);不要忘记srandom(time(NULL));在您的早期使用 例如 播种 PRNG main)。它可以很简单

char tmpbuf[80];
bool unique;
do { // in practice, this loop is extremely likely to run once
  snprintf(tmpbuf, sizeof(tmpbuf), "/tmp/mytemp_%lx_p%d.cc", 
           random(), (int)getpid());
  unique = access(tmpbuf, F_OK);
} while (unique);
// here tmpbuf contains a unique temporary file name
Run Code Online (Sandbox Code Playgroud)

你编码:

系统(“g++ -C”+code_string+”-o run.out”);

请注意,+通常不是字符串连接。您可以使用snprintf(3)asprintf(3)来构建字符串。或者在 C++ std::string中使用。如果你使用system(3)你应该检查它的返回码:

char cmdbuf[128];
snprintf(cmdbuf, sizeof(cmdbuf), "g++ -Wall -O %s -o run.out", tmpbuf);
fflush(NULL);
if (system(cmdbuf) != 0) {
   fprintf(stderr, "compilation %s failed\n", cmdbuf);
   exit(EXIT_FAILURE);
}
Run Code Online (Sandbox Code Playgroud)

顺便说一句,你的例子是错误的(缺少<stdio.h>);这是C代码,而不是C++代码。它应该是

echo -e '#include <stdio.h>\nint main(){printf("Hello World"); return 0;}' \
     |  gcc -x c -Wall -O -o myprog -
Run Code Online (Sandbox Code Playgroud)

附言。我的答案主要针对 Linux,但您可以根据您的操作系统进行调整。

  • 您还可以使用“-”而不是“/dev/stdin”(对于没有该设备的系统很有用):“echo ... | gcc -xc &lt;选项&gt; -` (2认同)