There is no meta data. The final execution is done by the underlying hardware because the compiler uses different instructions when doing some operations on these types. It becomes more obvious when you compare the assembly.
void test1()
{
char p = 0;
p += 3;
}
void test2()
{
unsigned char p = 0;
p += 3;
}
What you see here are the instructions compiled by the compiler form the source posted above. Compiled with no optimization -O0
this is the created assembly of clang 3.7. You can ignore most of the instructions, if you are not familiar with them. Keep the focus on movsx
and movzx
. These two instructions make the difference how the memory location is treated.
test1(): # Instructions for test1
push rbp
mov rbp, rsp
mov byte ptr [rbp - 1], 0
movsx eax, byte ptr [rbp - 1] <-- Move byte to word with sign-extension
add eax, 3
mov cl, al
mov byte ptr [rbp - 1], cl
pop rbp
ret
test2(): # Instructions for test2
push rbp
mov rbp, rsp
mov byte ptr [rbp - 1], 0
movzx eax, byte ptr [rbp - 1] <-- Move byte to word with zero-extension
add eax, 3
mov cl, al
mov byte ptr [rbp - 1], cl
pop rbp
ret