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

Can you pass your code directly into gcc? For example: gcc -? 'int main(){return 0;}'

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

例如:

g++ -? 'int main(){return 0;}'

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

system("g++ -C "+code_string+" -o run.out");

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

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

编辑:修复了它

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

您可以要求 GCC 从标准输入中读取。使用 /dev/stdin-:

阅读 Invoking GCC chapter of its documentation. Use its -x option
 echo 'int main(){return 0;}' | g++ -x c++ -O -Wall -o myprog /dev/stdin

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

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

以编程方式,您应该考虑使用 popen(3) to get a some FILE* handle for a pipe(7)(因此 FILE* f = popen("g++ -x c++ -O -Wall -o myprog /dev/stdin", "w"); 然后检查 f 是否不为空)和 fprintf 然后 pclose终于。不要忘记测试 pclose.

的状态

然而,GCC 花费的大部分时间并不是 parsing (use -ftime-report developer option to find out). You often want to ask it to optimize (with -O2 -march=native or just -O for example), and you surely want to ask for all warnings(至少 -Wall,也许还有 -Wextra)。

如果你想制作一些 plugin code in /tmp/someplugin.so from some emitted C++ code in /tmp/myemitted.cc to be dynamically loaded on Linux, compile it as position-independent code into a shared object dynamic library,例如

g++ -o /tmp/someplugin.so -fPIC -shared -Wall -O /tmp/myemitted.cc

etc....然后使用dlopen(3) on /tmp/someplugin.so with dlsym(3) to fetch some loaded symbols. My GCC MELT就是这样做的。

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

最后,最近的 GCC(至少使用 GCC 6) also has GCCJIT(实际上是 libgccjit)。您可以使用它来构建生成代码的一些表示,然后让 GCC 编译它。

另见 this and that. Read the C++ dlopen mini howto and the Program Library HowTo, and Drepper's How To Write Shared Libraries

I rather not make files

生成一个临时文件(参见 mkstemp(3) etc... and you practically could also general some random file name under /tmp/ ending with .c, then register its removal with atexit(3) passed some function doing unlink(2)...) is really quick (but you should build some kind of AST in memory before emitting C++ or C code from it). And using some Makefile to compile the generated code with some make command 的优点(对于高级用户)能够更改编译器或选项(通过编辑 Makefile 来配置 make) .

所以恕我直言,避免使用临时文件是错误的(请注意 gccg++ 也会生成和删除临时文件,例如包含一些汇编代码)。相反,我建议使用一些随机数(参见 random(3) 生成一个临时文件(匹配 /tmp/mytemp*.cc);不要忘记在 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

您编码:

system("g++ -C "+code_string+" -o run.out");

注意,+ 通常不是字符串连接。你可能会使用 snprintf(3) or asprintf(3) to build strings. Or use in C++ std::string. And if you use system(3) 你应该检查它的 return 代码:

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);
}

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

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

PS。我的回答集中在 Linux,但您可以针对您的 OS.

进行调整