Compiler errors won’t cause as many funny consequences with
gcc "$0" -o "$@".out && exec ./"$@".out || exit $? # I'd use ${0%.c} not $@
Love this trick too, but the difference, as far as I understand, is that it only works with a Bourne(-compatible) shell, whereas shebangs or binfmt_misc also work with exec().
The shell treats the first line as a comment. It executes the second line, which eventually exec's the binary so the rest of the file do not matter to the shell.
And the compiler treats the first line as a preprocessor directive, so it ignores the second line.
I initially misread/mistook the first line for a shebang.
You can also #embed the compiler binary, and execve it to much the same effect as binfmtc. I explored that trick for an IOCC entry that was never submitted because it ended up far too readable.
Yes, but it's not worth it. It's better to forget gcc and use tcc instead, which has the -run flag to compile and run without creating any intermediate file. It's also much quicker than gcc.
of course it is legitimized. I just meant that the selling point of binfmtc is that the same .c file can either be compiled by any C compiler, or executed directly.
We could perhaps split it into a two-file system where a "foo.sh" containing certain boilerplate will execute a "foo.c" that doesn't require any special conventions at all.
"foo.sh" could be identical for any .c file, and so we could symbolically link them all to a common file.
Of course, neither that file nor symlinks to it require a .sh suffix.
The contents might look like this:
#!/bin/sh
c_file=${0%.sh}.c
x_file=${0%.sh}.bin
# If cached executable file is missing, or out of date w.r.t.
# the source file, compile it:
if [ "$c_file" -nt "$x_file" ]; then
cc $CFLAGS "$c_file" -o "$x_file"
fi
# Run cached executable file
$x_file
C is still my first love. You can hold the whole language in your head, and it’s fast. Yes there are footguns but it’s a libertarian programming language - you’re responsible for what you build. No hand holding.
I like that too, but the problem is that C doesn't keep its end of the deal. No hand holding, but make what you are doing transparent. It used to be the case back in the 80s, but not anymore. Not with our optimizing compilers and oodles of UB and spec subtleties and implicit actions.
There's a similar cute trick for compiled OCaml scripts that we use with nbdkit: https://libguestfs.org/nbdkit-cc-plugin.3.html#Using-this-pl...