GCC uses libiconv to figure out how to transcode the bytes.
You can actually change this.
The compiler has an 'execution' character set that describes how characters should be interpreted at run time, and a 'source' character set, and they need not be the same.
Check this out
$ cat test_ebdic.c ; gcc -fexec-charset=EBCDIC-US test_ebdic.c ; ./a.out | xxd
#include <stdlib.h>
#include <stdio.h>
int main(void)
{
char data[] = "Hello";
printf("%s\n", data);
return EXIT_SUCCESS;
}
00000000: c885 9393 960a ......
The file was typed in UTF-8, and the compiler automatically translated the literal to EBCDIC-US to emit at run time. My terminal can't display this, so I view it with a hex editor.
Check out GLIBC, the standard libc implementation for GNU/Linux, or the easier to read, minimalist, alternative libc MUSL.
Bootlin, runs the Elixir Code Cross Referencer that lets you easily hop between files. For instance, Here is the code for printf in GLIBC.
If I am not mistaken, the argument made by papers like "C is not a low level language" is that C used to be a low level language, because it fit the architecture of a PDP, but a modern computer isn't a PDP, and so C isn't low level.
Did you know that
int history[10] = {0,0,0,0,0,0,0,0,0,0};
is the same thing as
int history[10] = {0};
And an idom in C would be to define a constant for the size like this
enum { HISTORY_MAX = 10};
int history[HISTORY_MAX] = {0};
int history_limit = HISTORY_MAX;