What to do if there is no printf (), fopen (), etc.
As long as you know how to interact with the system you are using, you can live without the standard C library. On embedded systems, where you only have a few kilobytes of memory, you probably don't want to use the standard library at all.
Here is the Hello World! example on Linux and Windows without using any standard C functions:
For example, on Linux, you can call Linux system calls directly in the built-in assembly:
#define SYSCALL_EXIT 60 #define SYSCALL_WRITE 1 void sys_exit(int error_code) { asm volatile ( "syscall" : : "a"(SYSCALL_EXIT), "D"(error_code) : "rcx", "r11", "memory" ); } int sys_write(unsigned fd, const char *buf, unsigned count) { unsigned ret; asm volatile ( "syscall" : "=a"(ret) : "a"(SYSCALL_WRITE), "D"(fd), "S"(buf), "d"(count) : "rcx", "r11", "memory" ); return ret; } int _start() { const char hwText[] = "Hello world!\n"; sys_write(1, hwText, sizeof(hwText)); sys_exit(12); return 0; }
Compile this with:
gcc -nostdlib nostd.c
And he displays Hello world! and comes out.
In Windows, system calls are not published, but are hidden behind another level of abstraction - kernel32.dll. It always loads when your program launches whether you want it or not. Thus, you can simply enable windows.h and use the Win32 API:
#include <windows.h> int _start() { const char str[] = "Hello world!\n"; HANDLE stdout = GetStdHandle(STD_OUTPUT_HANDLE); DWORD written; WriteFile(stdout, str, sizeof(str), &written, NULL); ExitProcess(12); return 0; }
windows.h has nothing to do with the standard C library, since you can also write Windows programs in any other language.
You can compile it using the MinGW tools, for example:
gcc -nostdlib C:\Windows\System32\kernel32.dll nostdlib.c
Then the compiler is smart enough to allow import dependencies and compile your program.
If you disassembled the program, you will see only your code, there is no standard library there.
So you can use C without a standard library.