Works fine for me:
Code: Select all
// >nul 2>&1 & @echo off
int dummy0(void) { // >nul 2>&1
int i; // >nul 2>&1 & goto bat
return 0; // >nul 2>&1
} // >nul 2>&1
#include <stdio.h>
int main(void)
{
printf("Welcome to the C/Batch hybrid!");
return 0;
};
/* >nul 2>&1
:bat
;@echo off
type %~n0.bat >> %~n0_C.c
tcc -o %~n0.exe %~n0_C.c
del %~n0_C.c
call %~n0.exe %*
del %~n0.exe
exit /b
*/ // >nul 2>&1
Output:
How do you change the compiler?
Change the line
Code: Select all
tcc -o %~n0.exe %~n0_C.c
Well, what if you WANT more batch?
Just add it in the multi-line comment. There are a few additions to trick the C code and to trick the Batch code, so it doesn't give a bunch of errors when loading this.
But how does it work???
Code: Select all
// >nul 2>&1 & @echo off
C Compiler perspective:
Hey, look, //! That's a single-line comment. I'm gonna ignore everything here, which in this case is ">nul 2>&1 & @echo off".
Batch Parser perspective:
I don't know what is the command //. Redirect it to stdout instead of stderr and redirect it to nul beacuse of >nul 2>&1. Wait, what's this &? Another command. This one says to do @echo off. I can do that! (does @echo off)
Code: Select all
int dummy0(void) { // >nul 2>&1
int i; // >nul 2>&1 & goto bat
return 0; // >nul 2>&1
} // >nul 2>&1
C Compiler perspective:
So basically, we make a function "dummy0" with int return type that returns 0 and defines "i".
Batch perspective:
What is that first line? Ignoring it.
The second? Hmm... so go to the label "bat". Okay.
The other ones? Yep, just ignore them.
Code: Select all
#include <stdio.h>
int main(void)
{
printf("Welcome to the C/Batch hybrid!");
return 0;
};
C Compiler perspective:
Print "Welcome to the C/Batch hybrid!" and leave.
Batch perspective:
(never loads this)
Code: Select all
/* >nul 2>&1
C perspective: Multi line comment! Ignoring...
Batch perspective: What is /*? Oh well, ignoring it.
Code: Select all
:bat
C perspective: Comment...
Batch perspective: Look, the label we were looking for! Go!
Code: Select all
;@echo off
type %~n0.bat >> %~n0_C.c
tcc -o %~n0.exe %~n0_C.c
del %~n0_C.c
call %~n0.exe %*
del %~n0.exe
exit /b
C perspective: Still a comment...
Batch perspective: So @echo off, and type this program's code to %~n0_C.c.
Alright, what's next? Ah, use tcc. Then, delete %~n0_C.c and let's call %~n0.exe with all of our arguments.
Next, we'll delete it and exit.
Code: Select all
*/ // >nul 2>&1
C perspective: End of multiline comment and start of single line comment. It contains >nul 2>&1.
Batch parser perspective: I have no idea what is */ //, but i'll not give an error.