Published on

My notes on C language

#include <stdio.h>

int main(void) {
    int charValue = 'A'; 
    int multiChar = 'AB'; 
    const char *stringValue = "ABC";    
    printf("Single char constant (int): %d\n", charValue);
    printf("Multi-char constant (int): %d\n", multiChar); 
    printf("String literal (const char *): %s\n", stringValue);     
    return 0;
}

why 'AB' evaluates to 16706

Packing (Little-Endian):

'AB' = 0x42 (B) 0x41 (A)
= 0x4241  (Hexadecimal)
= 16961 (Decimal)
'AB' = 0x41 (A) 0x42 (B)
= 0x4142  (Hexadecimal)
= 16706 (Decimal) 
hex(ord('A')), hex(ord('B'))  # 'A' = 0x41, 'B' = 0x42
int('0x4142', 16)  # 16706

String Literal:

  • "A" is a string (type const char *), which points to the memory address of A and a null terminator (\0).

in c99 standard section 5.1.2

  • All objects with static storage duration shall be initialized (set to their initial values) before program startup
{
 static int a;

 ++a;
 printf("%d\n", a);
}

prints 1 2 ...

if you remove static then you might get garbage values but wait try to run it

void fun(void) {
  int a;
  ++a;
  printf("%d\n", a);
}

int main(void) {

  fun();
  for (int i = 0; i < 20; ++i) {
    fun();
  }
}

you dont get garbage anymore

why?

on binary without for loop run this

objdump  -M intel -d binary
; this is assemnly without for loop
0000000000001139 <fun>:
    1139:	55                   	push   rbp
    113a:	48 89 e5             	mov    rbp,rsp
    113d:	48 83 ec 10          	sub    rsp,0x10
    1141:	83 45 fc 01          	add    DWORD PTR [rbp-0x4],0x1
    1145:	8b 45 fc             	mov    eax,DWORD PTR [rbp-0x4]
    1148:	89 c6                	mov    esi,eax
    114a:	48 8d 05 b3 0e 00 00 	lea    rax,[rip+0xeb3]        # 2004 <_IO_stdin_used+0x4>
    1151:	48 89 c7             	mov    rdi,rax
    1154:	b8 00 00 00 00       	mov    eax,0x0
    1159:	e8 d2 fe ff ff       	call   1030 <printf@plt>
    115e:	90                   	nop
    115f:	c9                   	leave
    1160:	c3                   	ret

0000000000001161 <main>:
    1161:	55                   	push   rbp
    1162:	48 89 e5             	mov    rbp,rsp
    1165:	e8 cf ff ff ff       	call   1139 <fun>
    116a:	b8 00 00 00 00       	mov    eax,0x0
    116f:	5d                   	pop    rbp
    1170:	c3                   	ret

look closely at line 1145 the stuff at [rbp-0x4] is to what is printed but we dont see any initialization of that in main function , dont believe me run it yourself with nasm.

section .text
    extern printf
    global _start

_start:
    call fun    
    call fun  
    call fun
    mov rax, 60
    xor rdi, rdi
    syscall

fun:
    push    rbp
    mov     rbp, rsp
    sub     rsp, 0x10
     add     dword  [rbp-0x4], 0x1

    mov     eax, dword  [rbp-0x4]
    mov     esi, eax

    lea     rdi, [fmt]

   mov eax,0x0
    call    printf

    nop
    leave
    ret

section .data
    fmt:      db "%d", 10, 0

now we will see assembly with for loop, well can you see line 1178 and this is initialized to 0 properly , currently i have no idea what the .. is going on here in generating assembly why compiler is getting it right initialization on this chance , whatever is this a compiler bug? i mean if you want to be wrong then be in both case dont give me false hopes, may be we shoudl try looking at clang and gcc source code

0000000000001139 <fun>:
    1139:	55                   	push   rbp
    113a:	48 89 e5             	mov    rbp,rsp
    113d:	48 83 ec 10          	sub    rsp,0x10
    1141:	83 45 fc 01          	add    DWORD PTR [rbp-0x4],0x1
    1145:	8b 45 fc             	mov    eax,DWORD PTR [rbp-0x4]
    1148:	89 c6                	mov    esi,eax
    114a:	48 8d 05 b3 0e 00 00 	lea    rax,[rip+0xeb3]        # 2004 <_IO_stdin_used+0x4>
    1151:	48 89 c7             	mov    rdi,rax
    1154:	b8 00 00 00 00       	mov    eax,0x0
    1159:	e8 d2 fe ff ff       	call   1030 <printf@plt>
    115e:	90                   	nop
    115f:	c9                   	leave
    1160:	c3                   	ret

0000000000001161 <main>:
    1161:	55                   	push   rbp
    1162:	48 89 e5             	mov    rbp,rsp
    1165:	48 83 ec 10          	sub    rsp,0x10
    1169:	e8 cb ff ff ff       	call   1139 <fun>
    116e:	e8 c6 ff ff ff       	call   1139 <fun>
    1173:	e8 c1 ff ff ff       	call   1139 <fun>
    1178:	c7 45 fc 00 00 00 00 	mov    DWORD PTR [rbp-0x4],0x0
    117f:	eb 09                	jmp    118a <main+0x29>
    1181:	e8 b3 ff ff ff       	call   1139 <fun>
    1186:	83 45 fc 01          	add    DWORD PTR [rbp-0x4],0x1
    118a:	83 7d fc 13          	cmp    DWORD PTR [rbp-0x4],0x13
    118e:	7e f1                	jle    1181 <main+0x20>
    1190:	b8 00 00 00 00       	mov    eax,0x0
    1195:	c9                   	leave
    1196:	c3                   	ret