To call printf("Hello!");
in C from terminal I use
echo '#include<stdio.h>
void main()
{
printf("Hello!");
}' > foo.c
and then call gcc foo.c
to make the output. Unfortunately, the pipelining
echo '#include<stdio.h>
void main()
{
printf("Hello!");
}' | gcc
fails complaining for no input file. Ultimately, I want to have a script where I can compile a C command
from terminal with ./script [command]
. Any suggestion would be appreciated.
Yes, but you have to specify the language using the
-x
option. Specify input file as stdin, language as C using-xc
(if you want it to be C++, use-xc++
). So in your case the command would beYou can read more about Command Line Compiler Arguments: see Invoking GCC chapter.
However, as @Basile says, it is not worth the effort to avoid dealing with C files. Check his answer for more information.
Instead of pipeing it, why not have the script run the command:
whilst still keeping the redirection into foo.c
You can then delete foo.c if you would like after gcc creates the executable by adding at the end
Other answers are explaining how to make
gcc
read C code from stdin, but notice that in practiceit is not worth the effort to avoid dealing with C files.
(I am guessing you are using some POSIX operating system like Linux; if not, adapt my answer to your OS and compiler)
Emitting C code automatically is usual practice (and many academic programming languages are compiling to C, and many builds are using generated C code, e.g. from bison). But there is no much gain to use pipes and stdin, because a C compiler takes a lot of time (notably for optimization, which you often want, e.g. by compiling with
gcc -O2
).So my recommendation is to put the generated C code in a genuine file (perhaps some temporary one which should be removed later appropriately). That file could be on some tmpfs file system if disk performance is an issue (and in practice it never is for
gcc
compiled source code), and that file could be temporary (e.g. removed later) if you want it to.Notice that the
gcc
program is generally using temporary files internally itself (e.g. for generated assembler files or object files). You'll see them if you add-v
to yourgcc
compilation command, e.g. if you compilefoo.c
withgcc -v foo.c -o fooprog
. So there is no practical reason to avoid a C source file (sincegcc
uses temporary files anyway!).If you want to generate code on the fly in a running program, you could generate temporary C code then compile it as a temporary plugin (with position-independent code) then dynamically load that plugin (e.g. using dlopen(3) & dlsym(3) on Linux); but you could also use JIT compiling libraries like GCCJIT or LLVM or asmjit, etc.... Of course this requires some support from your operating system (e.g. to grow your virtual address space): in pure standard C11 (read n1570), the set of functions is fixed at build time since defined in the union of your translation units (the set of
.c
files comprising your program), and you cannot generate code at runtime.If you want to generate some C program in some shell script, better use temporary files, e.g. with
tempfile
,mktemp
etc... (and usetrap
builtin onEXIT
and onTERM
signal to remove the temporary files when the script terminates).If you generate some temporary C code in your build, good build automation programs (e.g. GNU
make
orninja
) can be configured to remove these temporary C files (e.g. read about intermediate files formake
).Look also into homoiconic programming languages like Common Lisp. For example SBCL is compiling into machine code at every REPL interaction.
I have done this in the past by doing
Now
stdin.c
is a symlink to/dev/stdin
, i.e. a magic file "containing" anything I type or pipe to it. But the filename ends in.c
, so any C compiler should treat it as a C file. Things likework just fine.
(Obviously this assumes you're using a Unix-like system with symbolic links and
/dev/stdin
.)