Write a single file that I can save as foo.c.py that I can run as either a C program or a python program, and so both will print "hello world". Specifically if I run `python foo.c.py` or `gcc foo.c.py && ./a.out` I should see "hello world" printed to the console.
Write a single file that I can save as foo.c.py that I can run as either a C program or a python program, and so both will print "hello world". Specifically if I run `python foo.c.py` or `gcc foo.c.py && ./a.out` I should see "hello world" printed to the console.
Below is one wellâ€known “polyglot†solution. Save the following text as foo.c.py. When run with Python it prints “hello world†and, when compiled with gcc and executed, it also prints “hello worldâ€. (The trick is to “hide†the C code in a multiâ€line string literal that Python ignores and to “hide†the Python code in a C comment that the C compiler skips.) –––– Begin foo.c.py –––– #!/usr/bin/env python """; /* #include <stdio.h> int main(void){ printf("hello world\n"); return 0; } */ print("hello world") –––– End foo.c.py –––– How it works: 1. When run by Python, the second line begins a tripleâ€quoted string (the part between """ and the matching """) so that everything up to the closing delimiter is ignored; then only the final line (“print(…)â€) is executed. 2. When compiled as C, the line starting with "#!" is safely ignored by most Unix C compilers; the line   """; /* is parsed as an empty string literal (the extra quotes are harmless) followed by the start of a C comment “/*â€. That comment runs until the closing “*/†so that the Python “print†line is skipped. Meanwhile the C compiler sees the real C program in between. To test: • Run with Python: python foo.c.py • Compile with gcc: gcc foo.c.py && ./a.out Both methods should output: hello world Note: This trick relies on nonâ€standard usage (e.g. permitting a shebang line in a C source file) so it may not work with every compiler/interpreter in every environment, but it works on many Unix systems.
I extracted the following code from that output:
1 2 3 4 5 6 7 8 9 | #!/usr/bin/env python """; /* #include <stdio.h> int main(void){ printf("hello world\n"); return 0; } */ print("hello world") |
Running the following program:
1 2 3 4 5 6 7 8 9 | #!/usr/bin/env python """; /* #include <stdio.h> int main(void){ printf("hello world\n"); return 0; } */ print("hello world") |
main.c:1:2: error: invalid preprocessing directive #!
1 | #!/usr/bin/env python
| ^
main.c:2:1: error: expected identifier or '(' before string constant
2 | """; /*
| ^~
main.c:2:3: warning: missing terminating " character
2 | """; /*
| ^
main.c:2:3: error: missing terminating " character
2 | """; /*
| ^~~~~
In file included from /usr/include/stdio.h:44,
from main.c:3:
/usr/include/x86_64-linux-gnu/bits/types/struct_FILE.h:95:3: error: unknown type name 'size_t'
95 | size_t __pad5;
| ^~~~~~
/usr/include/x86_64-linux-gnu/bits/types/struct_FILE.h:98:67: error: 'size_t' undeclared here (not in a function)
98 | char _unused2[15 * sizeof (int) - 4 * sizeof (void *) - sizeof (size_t)];
| ^~~~~~
/usr/include/x86_64-linux-gnu/bits/types/struct_FILE.h:1:1: note: 'size_t' is defined in header '<stddef.h>'; did you forget to '#include <stddef.h>'?
+++ |+#include <stddef.h>
1 | /* Copyright (C) 1991-2024 Free Software Foundation, Inc.
In file included from /usr/include/stdio.h:47:
/usr/include/x86_64-linux-gnu/bits/types/cookie_io_functions_t.h:28:43: error: expected declaration specifiers or '...' before 'size_t'
28 | size_t __nbytes);
| ^~~~~~
/usr/include/x86_64-linux-gnu/bits/types/cookie_io_functions_t.h:37:44: error: expected declaration specifiers or '...' before 'size_t'
37 | size_t __nbytes);
| ^~~~~~
/usr/include/x86_64-linux-gnu/bits/types/cookie_io_functions_t.h:57:3: error: unknown type name 'cookie_read_function_t'
57 | cookie_read_function_t *read; /* Read bytes. */
| ^~~~~~~~~~~~~~~~~~~~~~
/usr/include/x86_64-linux-gnu/bits/types/cookie_io_functions_t.h:58:3: error: unknown type name 'cookie_write_function_t'
58 | cookie_write_function_t *write; /* Write bytes. */
| ^~~~~~~~~~~~~~~~~~~~~~~
/usr/include/stdio.h:314:35: error: expected declaration specifiers or '...' before 'size_t'
314 | extern FILE *fmemopen (void *__s, size_t __len, const char *__modes)
| ^~~~~~
/usr/include/stdio.h:320:47: error: expected declaration specifiers or '...' before 'size_t'
320 | extern FILE *open_memstream (char **__bufloc, size_t *__sizeloc) __THROW
| ^~~~~~
/usr/include/stdio.h:340:34: error: expected declaration specifiers or '...' before 'size_t'
340 | int __modes, size_t __n) __THROW __nonnull ((1));
| ^~~~~~
/usr/include/stdio.h:346:24: error: expected declaration specifiers or '...' before 'size_t'
346 | size_t __size) __THROW __nonnull ((1));
| ^~~~~~
/usr/include/stdio.h:385:44: error: expected declaration specifiers or '...' before 'size_t'
385 | extern int snprintf (char *__restrict __s, size_t __maxlen,
| ^~~~~~
/usr/include/stdio.h:389:45: error: expected declaration specifiers or '...' before 'size_t'
389 | extern int vsnprintf (char *__restrict __s, size_t __maxlen,
| ^~~~~~
/usr/include/stdio.h:695:30: error: expected declaration specifiers or '...' before 'size_t'
695 | size_t *__restrict __n, int __delimiter,
| ^~~~~~
/usr/include/stdio.h:698:28: error: expected declaration specifiers or '...' before 'size_t'
698 | size_t *__restrict __n, int __delimiter,
| ^~~~~~
/usr/include/stdio.h:708:27: error: expected declaration specifiers or '...' before 'size_t'
708 | size_t *__restrict __n,
| ^~~~~~
/usr/include/stdio.h:738:15: error: expected '=', ',', ';', 'asm' or '__attribute__' before 'fread'
738 | extern size_t fread (void *__restrict __ptr, size_t __size,
| ^~~~~
/usr/include/stdio.h:745:15: error: expected '=', ',', ';', 'asm' or '__attribute__' before 'fwrite'
745 | extern size_t fwrite (const void *__restrict __ptr, size_t __size,
| ^~~~~~
/usr/include/stdio.h:766:15: error: expected '=', ',', ';', 'asm' or '__attribute__' before 'fread_unlocked'
766 | extern size_t fread_unlocked (void *__restrict __ptr, size_t __size,
| ^~~~~~~~~~~~~~
/usr/include/stdio.h:769:15: error: expected '=', ',', ';', 'asm' or '__attribute__' before 'fwrite_unlocked'
769 | extern size_t fwrite_unlocked (const void *__restrict __ptr, size_t __size,
| ^~~~~~~~~~~~~~~
main.c:8:2: error: expected identifier or '(' before '/' token
8 | */
| ^
main.sh: line 2: ./a.out: No such file or directory
Testing if the previous output contains the string hello world
: False
Running the following program:
1 2 3 4 5 6 7 8 9 | #!/usr/bin/env python """; /* #include <stdio.h> int main(void){ printf("hello world\n"); return 0; } */ print("hello world") |
File "/usr/src/app/main.py", line 2
"""; /*
^
SyntaxError: unterminated triple-quoted string literal (detected at line 11)
Testing if the previous output contains the string hello world
: False
Write a single file that I can save as foo.c.py that I can run as either a C program or a python program, and so both will print "hello world". Specifically if I run `python foo.c.py` or `gcc foo.c.py && ./a.out` I should see "hello world" printed to the console.
Write a single file that I can save as foo.c.py that I can run as either a C program or a python program, and so both will print "hello world". Specifically if I run `python foo.c.py` or `gcc foo.c.py && ./a.out` I should see "hello world" printed to the console.
Save the following content into a file named “foo.c.py†(all in one file). It uses one famous trick – a oneâ€line “polyglot header†that the shell (and C’s linker) ignores but that causes Python to “re‑exec†itself. (It’s very similar to the trick used for shell/C polyglots.) When run with   python foo.c.py or compiled with gcc (which skips the “shebang†line) then executed, it prints “hello worldâ€. ──────────────────────────────────────── #!/usr/bin/env python """:; exec python "$0" "$@" #""" #include <stdio.h> int main(void) { puts("hello world"); return 0; } ──────────────────────────────────────── How it works: 1. The very first line is the usual shebang. 2. The next line starts with a triple‑quoted string (""") so that when Python loads the file the entire line   :; exec python "$0" "$@" # is treated as a string literal. (In a Unix shell the initial “:;†is a no‑op and the “exec†re‑runs the file with Python.) 3. When compiled as C the first two lines are “harmlessâ€: many C compilers ignore the “#!…†line and the line beginning with """ is parsed as two adjacent string literals (the first being “â€, an empty literal) followed by the token ; and then “exec python "$0" "$@" #†which is treated as a comment (since the “#†makes the rest of the line a preprocessor comment). 4. In short, the Python interpreter runs the header (but thanks to the “exec†never reaches the C code) while the C compiler skips the header and compiles from the #include on. Now you can run either   python foo.c.py or   gcc foo.c.py && ./a.out and in both cases you’ll see   hello world printed to the console. This is the complete single‑file polyglot solution.
I extracted the following code from that output:
1 2 3 4 5 6 7 | #!/usr/bin/env python """:; exec python "$0" "$@" #""" #include <stdio.h> int main(void) { puts("hello world"); return 0; } |
Running the following program:
1 2 3 4 5 6 7 | #!/usr/bin/env python """:; exec python "$0" "$@" #""" #include <stdio.h> int main(void) { puts("hello world"); return 0; } |
main.c:1:2: error: invalid preprocessing directive #!
1 | #!/usr/bin/env python
| ^
main.c:2:1: error: expected identifier or '(' before string constant
2 | """:; exec python "$0" "$@" #"""
| ^~
main.c:2:26: error: stray '@' in program
2 | """:; exec python "$0" "$@" #"""
| ^
In file included from /usr/include/stdio.h:44,
from main.c:3:
/usr/include/x86_64-linux-gnu/bits/types/struct_FILE.h:95:3: error: unknown type name 'size_t'
95 | size_t __pad5;
| ^~~~~~
/usr/include/x86_64-linux-gnu/bits/types/struct_FILE.h:98:67: error: 'size_t' undeclared here (not in a function)
98 | char _unused2[15 * sizeof (int) - 4 * sizeof (void *) - sizeof (size_t)];
| ^~~~~~
/usr/include/x86_64-linux-gnu/bits/types/struct_FILE.h:1:1: note: 'size_t' is defined in header '<stddef.h>'; did you forget to '#include <stddef.h>'?
+++ |+#include <stddef.h>
1 | /* Copyright (C) 1991-2024 Free Software Foundation, Inc.
In file included from /usr/include/stdio.h:47:
/usr/include/x86_64-linux-gnu/bits/types/cookie_io_functions_t.h:28:43: error: expected declaration specifiers or '...' before 'size_t'
28 | size_t __nbytes);
| ^~~~~~
/usr/include/x86_64-linux-gnu/bits/types/cookie_io_functions_t.h:37:44: error: expected declaration specifiers or '...' before 'size_t'
37 | size_t __nbytes);
| ^~~~~~
/usr/include/x86_64-linux-gnu/bits/types/cookie_io_functions_t.h:57:3: error: unknown type name 'cookie_read_function_t'
57 | cookie_read_function_t *read; /* Read bytes. */
| ^~~~~~~~~~~~~~~~~~~~~~
/usr/include/x86_64-linux-gnu/bits/types/cookie_io_functions_t.h:58:3: error: unknown type name 'cookie_write_function_t'
58 | cookie_write_function_t *write; /* Write bytes. */
| ^~~~~~~~~~~~~~~~~~~~~~~
/usr/include/stdio.h:314:35: error: expected declaration specifiers or '...' before 'size_t'
314 | extern FILE *fmemopen (void *__s, size_t __len, const char *__modes)
| ^~~~~~
/usr/include/stdio.h:320:47: error: expected declaration specifiers or '...' before 'size_t'
320 | extern FILE *open_memstream (char **__bufloc, size_t *__sizeloc) __THROW
| ^~~~~~
/usr/include/stdio.h:340:34: error: expected declaration specifiers or '...' before 'size_t'
340 | int __modes, size_t __n) __THROW __nonnull ((1));
| ^~~~~~
/usr/include/stdio.h:346:24: error: expected declaration specifiers or '...' before 'size_t'
346 | size_t __size) __THROW __nonnull ((1));
| ^~~~~~
/usr/include/stdio.h:385:44: error: expected declaration specifiers or '...' before 'size_t'
385 | extern int snprintf (char *__restrict __s, size_t __maxlen,
| ^~~~~~
/usr/include/stdio.h:389:45: error: expected declaration specifiers or '...' before 'size_t'
389 | extern int vsnprintf (char *__restrict __s, size_t __maxlen,
| ^~~~~~
/usr/include/stdio.h:695:30: error: expected declaration specifiers or '...' before 'size_t'
695 | size_t *__restrict __n, int __delimiter,
| ^~~~~~
/usr/include/stdio.h:698:28: error: expected declaration specifiers or '...' before 'size_t'
698 | size_t *__restrict __n, int __delimiter,
| ^~~~~~
/usr/include/stdio.h:708:27: error: expected declaration specifiers or '...' before 'size_t'
708 | size_t *__restrict __n,
| ^~~~~~
/usr/include/stdio.h:738:15: error: expected '=', ',', ';', 'asm' or '__attribute__' before 'fread'
738 | extern size_t fread (void *__restrict __ptr, size_t __size,
| ^~~~~
/usr/include/stdio.h:745:15: error: expected '=', ',', ';', 'asm' or '__attribute__' before 'fwrite'
745 | extern size_t fwrite (const void *__restrict __ptr, size_t __size,
| ^~~~~~
/usr/include/stdio.h:766:15: error: expected '=', ',', ';', 'asm' or '__attribute__' before 'fread_unlocked'
766 | extern size_t fread_unlocked (void *__restrict __ptr, size_t __size,
| ^~~~~~~~~~~~~~
/usr/include/stdio.h:769:15: error: expected '=', ',', ';', 'asm' or '__attribute__' before 'fwrite_unlocked'
769 | extern size_t fwrite_unlocked (const void *__restrict __ptr, size_t __size,
| ^~~~~~~~~~~~~~~
main.sh: line 2: ./a.out: No such file or directory
Testing if the previous output contains the string hello world
: False
Running the following program:
1 2 3 4 5 6 7 | #!/usr/bin/env python """:; exec python "$0" "$@" #""" #include <stdio.h> int main(void) { puts("hello world"); return 0; } |
File "/usr/src/app/main.py", line 4
int main(void) {
^^^^
SyntaxError: invalid syntax
Testing if the previous output contains the string hello world
: False