RetroFed Forums
Your home away from modern life.
Why does the compiler understand ASCII by default?
Post Reply
AuthorMessage
printf("%s", name); piefed.blahaj.zone akunohana@piefed.blahaj.zone
Joined: 2026-03-30
(edited) Quote

Environment\
Compiler Clang on Termux on Samsung's One UI 7 on a Samsung Galaxy Tab A9+

The title is an assumption on it's own, so feel free to correct it/me!

I was experimenting with sanitizing user input, read to a character array with fgets. Specifically, I was trying to have a for loop remove (skip) certain input. Here is the code:

for (n = strlen(input) - 1; n >= 0; n--) { if (input[n] >= 0x30 && input[n] <= 0x39 || input[n] == ' ' || input[n] == '\t') { input[n] = 0x18; } }  

While the program does behave as I want it to, I don't understand why it seemlingy by default understands that the various hex codes refer to the character encoding as per the ASCII table. I cated my tablet's filesystem encoding at /sys/fs/f2fs/dm-44/encoding, which yielded UTF-8. If I understand it correctly, the first 128 code points of Unicode are the same as ASCII's. But according to this article on Wikipedia, there are no hexadecimal references in Unicode, only octal and decimal.

If the underlying filesystem uses UTF-8, and Unicode code points are not referred to by hex, how then does my compiler (Clang) understand what ASCII code points I'm referring to?

Is there some conversion going on under the hood that I am not aware of? I did find a libxml2/libxml/encoding.h, which contains comments about some conversion to and from UTF-8. Is this it? I can't make head or tails of it because of my limited C knowledge...

6   Original
CameronDev programming.dev CameronDev@programming.dev
Joined: 2023-06-18
#2 · Quote Reply

You are inspecting a byte, which contains 0x39. That it corresponds to "9" doesn't matter at all to the compiler at all. If you were on a system that didn't match "9" <=> 0x39 it would still replace those byte values.

3
kubica fedia.io kubica@fedia.io
Joined: 2024-07-02
#3 · Quote Reply

Maybe this is a bit too much if you are just starting but read the first paragraph at least and then also look at "Relationship to ASCII" and "Relationship to Unicode"

https://en.wikipedia.org/wiki/Code_page

3
printf("%s", name); piefed.blahaj.zone akunohana@piefed.blahaj.zone
Joined: 2026-03-30
#4 · Quote Reply

You are inspecting a byte, which contains 0x39. That it corresponds to "9" doesn't matter at all to the compiler at all. If you were on a system that didn't match "9" &lt;=&gt; 0x39 it would still replace those byte values.

Thanks! I'll have to noodle this around a bit because it's hard for me to understand. xD

2
printf("%s", name); piefed.blahaj.zone akunohana@piefed.blahaj.zone
Joined: 2026-03-30
#5 · Quote Reply

Maybe this is a bit too much if you are just starting but read the first paragraph at least and then also look at "Relationship to ASCII" and "Relationship to Unicode" https://en.wikipedia.org/wiki/Code_page

Thanks! Every piece of advice is appreciated! :D

1
modeler lemmy.world modeler@lemmy.world
Joined: 2023-08-04
#6 · Quote Reply

I C (and most other languages) you can enter a value like thirty-two using many different number bases: ‘ ‘ as a char, 32 in decimal, 0x20 is hex, 040 in octal or 0b00010000. All of these mean thirty-two, just written differently using different characters.

Note that each of these representations use different digits and/or letters to specify the same number - the mathematical entity thirty-two. These letters and digits are characters stored as numbers, eg the digit zero (0) is coded in ASCII as 48.

In the end, the C compiler will compile the text ‘32’, ‘0x40’ or ‘0b00010000’ into binary and store it in memory the single byte where the 5th bit set to 1 and the others to 0. This is the way computer memory is used to represent the number, and it’s linked to the way the electric circuits do things like add numbers together.

The compiler is the thing that understands that the characters like ‘3’, ‘+’ or ‘F’ and works out what they represent (a number, a variable name or a sum). When it understands that, it will turn the code into bits that the CPU can work with, for example passing it to the compare instruction CMP used to test whether the input is less than the number thirty-two.

This is very meta, and I hope this clarifies rather than confuses. Compilers are notoriously confusing, such as the thought ‘the compiler compiles the compiler code into an executable that can compile itself’.

7
CameronDev programming.dev CameronDev@programming.dev
Joined: 2023-06-18
#7 · Quote Reply

Thanks! I'll have to noodle this around a bit because it's hard for me to understand. xD

I dunno if this helps, but this screenshot shows the memory view of a program with a string. The hex representation in the middle is what is actually stored in memory. Each pair is one byte/char, and that is what your input[n] <= 0x39 is comparing against.

3
avidya programming.dev avidya@programming.dev
Joined: 2026-05-10
#8 · (edited) Quote Reply

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.

2
printf("%s", name); piefed.blahaj.zone akunohana@piefed.blahaj.zone
Joined: 2026-03-30
#9 · Quote Reply

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 &lt;stdlib.h&gt; #include &lt;stdio.h&gt; int main(void) { char data[] = "Hello"; printf("%s...

Sic!!! Thank you so much! I'll try this as soon as my new Gentoo system is up and running! Just to have another excuse for me to set it up already. 🤣

Is it gcc or the OS that determines what encodings I can pass as an option to the compiler?

1
avidya programming.dev avidya@programming.dev
Joined: 2026-05-10
#10 · Quote Reply

Sic!!! Thank you so much! I'll try this as soon as my new Gentoo system is up and running! Just to have another excuse for me to set it up already. 🤣 Is it gcc or the OS that determines what encodings I can pass as an option to the compiler?

GCC uses libiconv to figure out how to transcode the bytes.

2
Post Reply
Back to top