I sometimes want to try something very short just to confirm
semantics. Since creating a temporary file and putting in the
boilerplate takes more than 30 seconds, I have this script:
#!/bin/sh
body="$1"
out=$(mktemp /tmp/ccrun-XXXXXX)
src=${out}.c
cat > ${src} <<EOF
#include <limits.h>
#include <string.h>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#define UNUSED __attribute__((unused))
int main(int UNUSED argc,char UNUSED *argv[])
{
EOF
echo "$body" >> ${src}
echo -e "return 0;\n}" >> ${src}
cc -std=c99 -Wall -Wextra ${CCRUN_FLAGS} -o ${out} ${src} -lm
shift
echo ${out} "$@"
${out} "$@"
#rm ${out} ${src}
A sample invocation (this code statically initializes an array of function pointers) looks like:
$ ccrun 'int f(int a){return a+1;} int g(int a){return a+2;} int (*farr[2])(int) = {f,g}; for (int i=0; i<2; i++) printf("%d %d\n",i,farr[i](i));'
/tmp/ccrun-6nT4Wo
0 1
1 3
If I want to make little changes, I just edit the command line.
If it becomes unweildy on the command line, I'll edit the
temporary file, in this case /tmp/ccrun-6nT4Wo.c. Command line
arguments to the executable can be given after the program (first
argument). The executable is left in place so it can be run
without recompiling. You can do something similar for any
language.