void trick3() {
  char str1[] = {'A', 'B', 'C', 'D', 'E'};
  char str2[] = "ABCDE";
  char *str3 = "ABCDE";
  char *cPtr = str1;
  short sArr[] = {1, 2, 3, 4, 5};
  short sArr2D[][5] = {{1, 2, 3, 4, 5}, {6, 7, 8, 9, 10}};
  short *sPtr1 = sArr;
  short(*sPtr2)[5] = sArr2D;
  short *sPtr3[5];
  printf("sizeof(str1) = %u\n", sizeof(str1));
  printf("sizeof(str2) = %u\n", sizeof(str2));
  printf("sizeof(str3) = %u\n", sizeof(str3));
  printf("sizeof(cPtr) = %u\n", sizeof(cPtr));
  printf("\n");
  printf("sizeof(sArr) = %u\n", sizeof(sArr));
  printf("sizeof(sPtr1) = %u\n", sizeof(sPtr1));
  printf("sizeof(sArr2D) = %u\n", sizeof(sArr2D));
  printf("sizeof(sPtr2) = %u\n", sizeof(sPtr2));
  printf("sizeof(*sPtr2) = %u\n", sizeof(*sPtr2));
  printf("sizeof(sPtr3) = %u\n", sizeof(sPtr3));
  printf("\n");
  printf("sArr2D[1][2] = %d\n", sArr2D[1][2]);
  printf("sPtr2[0][0] = %d, sPtr2[1][2] = %d\n", sPtr2[0][0], sPtr2[1][2]);
  printf("*(* (sArr2D + 1) + 2) = %d\n", *(*(sArr2D + 1) + 2));
  printf("*(*(sArr2D) + 1*5 + 2) = %d\n\n", *(*(sArr2D) + 1 * 5 + 2));
}


x86 assembly (clang, -O0):
<trick3>:
push   %rbp
mov    %rsp,%rbp
sub    $0x80,%rsp
mov    0xedf(%rip),%eax
mov    %eax,-0x5(%rbp)
mov    0xeda(%rip),%al
mov    %al,-0x1(%rbp)
mov    0xef1(%rip),%eax
mov    %eax,-0xb(%rbp)
mov    0xeeb(%rip),%ax
mov    %ax,-0x7(%rbp)
lea    0xedc(%rip),%rax
mov    %rax,-0x18(%rbp)
lea    -0x5(%rbp),%rax
mov    %rax,-0x20(%rbp)
mov    0xeab(%rip),%rax
mov    %rax,-0x2a(%rbp)
mov    0xea8(%rip),%ax
mov    %ax,-0x22(%rbp)
mov    0xe9f(%rip),%rax
mov    %rax,-0x40(%rbp)
mov    0xe9c(%rip),%rax
mov    %rax,-0x38(%rbp)
mov    0xe9a(%rip),%eax
mov    %eax,-0x30(%rbp)
lea    -0x2a(%rbp),%rax
mov    %rax,-0x48(%rbp)
lea    -0x40(%rbp),%rax
mov    %rax,-0x50(%rbp)
lea    0xe8a(%rip),%rdi
mov    $0x5,%esi
mov    $0x0,%al
call   1030 <printf@plt>
lea    0xe8a(%rip),%rdi
mov    $0x6,%esi
mov    $0x0,%al
call   1030 <printf@plt>
lea    0xe8a(%rip),%rdi
mov    $0x8,%esi
mov    $0x0,%al
call   1030 <printf@plt>
lea    0xe8a(%rip),%rdi
mov    $0x8,%esi
mov    $0x0,%al
call   1030 <printf@plt>
lea    0xf72(%rip),%rdi
mov    $0x0,%al
call   1030 <printf@plt>
lea    0xe7c(%rip),%rdi
mov    $0xa,%esi
mov    $0x0,%al
call   1030 <printf@plt>
lea    0xe7c(%rip),%rdi
mov    $0x8,%esi
mov    $0x0,%al
call   1030 <printf@plt>
lea    0xe7d(%rip),%rdi
mov    $0x14,%esi
mov    $0x0,%al
call   1030 <printf@plt>
lea    0xe7f(%rip),%rdi
mov    $0x8,%esi
mov    $0x0,%al
call   1030 <printf@plt>
lea    0xe80(%rip),%rdi
mov    $0xa,%esi
mov    $0x0,%al
call   1030 <printf@plt>
lea    0xe82(%rip),%rdi
mov    $0x28,%esi
mov    $0x0,%al
call   1030 <printf@plt>
lea    0xef2(%rip),%rdi
mov    $0x0,%al
call   1030 <printf@plt>
movswl -0x32(%rbp),%esi
lea    0xe71(%rip),%rdi
mov    $0x0,%al
call   1030 <printf@plt>
mov    -0x50(%rbp),%rax
movswl (%rax),%esi
mov    -0x50(%rbp),%rax
movswl 0xe(%rax),%edx
lea    0xe67(%rip),%rdi
mov    $0x0,%al
call   1030 <printf@plt>
movswl -0x32(%rbp),%esi
lea    0xe79(%rip),%rdi
mov    $0x0,%al
call   1030 <printf@plt>
movswl -0x32(%rbp),%esi
lea    0xe83(%rip),%rdi
mov    $0x0,%al
call   1030 <printf@plt>
add    $0x80,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<trick3>:
push   %rax
lea    0xed8(%rip),%rdi
mov    $0x5,%esi
xor    %eax,%eax
call   1040 <printf@plt>
lea    0xed8(%rip),%rdi
mov    $0x6,%esi
xor    %eax,%eax
call   1040 <printf@plt>
lea    0xed8(%rip),%rdi
mov    $0x8,%esi
xor    %eax,%eax
call   1040 <printf@plt>
lea    0xed8(%rip),%rdi
mov    $0x8,%esi
xor    %eax,%eax
call   1040 <printf@plt>
mov    $0xa,%edi
call   1030 <putchar@plt>
lea    0xece(%rip),%rdi
mov    $0xa,%esi
xor    %eax,%eax
call   1040 <printf@plt>
lea    0xece(%rip),%rdi
mov    $0x8,%esi
xor    %eax,%eax
call   1040 <printf@plt>
lea    0xecf(%rip),%rdi
mov    $0x14,%esi
xor    %eax,%eax
call   1040 <printf@plt>
lea    0xed1(%rip),%rdi
mov    $0x8,%esi
xor    %eax,%eax
call   1040 <printf@plt>
lea    0xed2(%rip),%rdi
mov    $0xa,%esi
xor    %eax,%eax
call   1040 <printf@plt>
lea    0xed4(%rip),%rdi
mov    $0x28,%esi
xor    %eax,%eax
call   1040 <printf@plt>
mov    $0xa,%edi
call   1030 <putchar@plt>
lea    0xecb(%rip),%rdi
mov    $0x8,%esi
xor    %eax,%eax
call   1040 <printf@plt>
lea    0xecb(%rip),%rdi
mov    $0x1,%esi
mov    $0x8,%edx
xor    %eax,%eax
call   1040 <printf@plt>
lea    0xed7(%rip),%rdi
mov    $0x8,%esi
xor    %eax,%eax
call   1040 <printf@plt>
lea    0xee0(%rip),%rdi
mov    $0x8,%esi
xor    %eax,%eax
pop    %rcx
jmp    1040 <printf@plt>

LLVM IR (-O0):
@__const.trick3.str1 = [5 x i8] c"ABCDE"
@__const.trick3.str2 = [6 x i8] c"ABCDE\00"
@.str = [6 x i8] c"ABCDE\00"
@__const.trick3.sArr = [5 x i16] [i16 1, i16 2, i16 3, i16 4, i16 5]
@__const.trick3.sArr2D = [2 x [5 x i16]] [[5 x i16] [i16 1, i16 2, i16 3, i16 4, i16 5], [5 x i16] [i16 6, i16 7, i16 8, i16 9, i16 10]]
@.str.1 = [19 x i8] c"sizeof(str1) = %u\0A\00"
@.str.2 = [19 x i8] c"sizeof(str2) = %u\0A\00"
@.str.3 = [19 x i8] c"sizeof(str3) = %u\0A\00"
@.str.4 = [19 x i8] c"sizeof(cPtr) = %u\0A\00"
@.str.5 = [2 x i8] c"\0A\00"
@.str.6 = [19 x i8] c"sizeof(sArr) = %u\0A\00"
@.str.7 = [20 x i8] c"sizeof(sPtr1) = %u\0A\00"
@.str.8 = [21 x i8] c"sizeof(sArr2D) = %u\0A\00"
@.str.9 = [20 x i8] c"sizeof(sPtr2) = %u\0A\00"
@.str.10 = [21 x i8] c"sizeof(*sPtr2) = %u\0A\00"
@.str.11 = [20 x i8] c"sizeof(sPtr3) = %u\0A\00"
@.str.12 = [19 x i8] c"sArr2D[1][2] = %d\0A\00"
@.str.13 = [36 x i8] c"sPtr2[0][0] = %d, sPtr2[1][2] = %d\0A\00"
@.str.14 = [28 x i8] c"*(* (sArr2D + 1) + 2) = %d\0A\00"
@.str.15 = [30 x i8] c"*(*(sArr2D) + 1*5 + 2) = %d\0A\0A\00"
define void @trick3() {
%1 = alloca [5 x i8]
%2 = alloca [6 x i8]
%3 = alloca i8*
%4 = alloca i8*
%5 = alloca [5 x i16]
%6 = alloca [2 x [5 x i16]]
%7 = alloca i16*
%8 = alloca [5 x i16]*
%9 = alloca [5 x i16*]
%10 = bitcast [5 x i8]* %1 to i8*
%11 = bitcast [6 x i8]* %2 to i8*
store i8* getelementptr inbounds ([6 x i8], [6 x i8]* @.str, i64 0, i64 0), i8** %3
%12 = getelementptr inbounds [5 x i8], [5 x i8]* %1, i64 0, i64 0
store i8* %12, i8** %4
%13 = bitcast [5 x i16]* %5 to i8*
%14 = bitcast [2 x [5 x i16]]* %6 to i8*
%15 = getelementptr inbounds [5 x i16], [5 x i16]* %5, i64 0, i64 0
store i16* %15, i16** %7
%16 = getelementptr inbounds [2 x [5 x i16]], [2 x [5 x i16]]* %6, i64 0, i64 0
store [5 x i16]* %16, [5 x i16]** %8
%17 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([19 x i8], [19 x i8]* @.str.1, i64 0, i64 0), i64 5)
%18 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([19 x i8], [19 x i8]* @.str.2, i64 0, i64 0), i64 6)
%19 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([19 x i8], [19 x i8]* @.str.3, i64 0, i64 0), i64 8)
%20 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([19 x i8], [19 x i8]* @.str.4, i64 0, i64 0), i64 8)
%21 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([2 x i8], [2 x i8]* @.str.5, i64 0, i64 0))
%22 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([19 x i8], [19 x i8]* @.str.6, i64 0, i64 0), i64 10)
%23 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([20 x i8], [20 x i8]* @.str.7, i64 0, i64 0), i64 8)
%24 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([21 x i8], [21 x i8]* @.str.8, i64 0, i64 0), i64 20)
%25 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([20 x i8], [20 x i8]* @.str.9, i64 0, i64 0), i64 8)
%26 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([21 x i8], [21 x i8]* @.str.10, i64 0, i64 0), i64 10)
%27 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([20 x i8], [20 x i8]* @.str.11, i64 0, i64 0), i64 40)
%28 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([2 x i8], [2 x i8]* @.str.5, i64 0, i64 0))
%29 = getelementptr inbounds [2 x [5 x i16]], [2 x [5 x i16]]* %6, i64 0, i64 1
%30 = getelementptr inbounds [5 x i16], [5 x i16]* %29, i64 0, i64 2
%31 = load i16, i16* %30
%32 = sext i16 %31 to i32
%33 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([19 x i8], [19 x i8]* @.str.12, i64 0, i64 0), i32 %32)
%34 = load [5 x i16]*, [5 x i16]** %8
%35 = getelementptr inbounds [5 x i16], [5 x i16]* %34, i64 0
%36 = getelementptr inbounds [5 x i16], [5 x i16]* %35, i64 0, i64 0
%37 = load i16, i16* %36
%38 = sext i16 %37 to i32
%39 = load [5 x i16]*, [5 x i16]** %8
%40 = getelementptr inbounds [5 x i16], [5 x i16]* %39, i64 1
%41 = getelementptr inbounds [5 x i16], [5 x i16]* %40, i64 0, i64 2
%42 = load i16, i16* %41
%43 = sext i16 %42 to i32
%44 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([36 x i8], [36 x i8]* @.str.13, i64 0, i64 0), i32 %38, i32 %43)
%45 = getelementptr inbounds [2 x [5 x i16]], [2 x [5 x i16]]* %6, i64 0, i64 0
%46 = getelementptr inbounds [5 x i16], [5 x i16]* %45, i64 1
%47 = getelementptr inbounds [5 x i16], [5 x i16]* %46, i64 0, i64 0
%48 = getelementptr inbounds i16, i16* %47, i64 2
%49 = load i16, i16* %48
%50 = sext i16 %49 to i32
%51 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([28 x i8], [28 x i8]* @.str.14, i64 0, i64 0), i32 %50)
%52 = getelementptr inbounds [2 x [5 x i16]], [2 x [5 x i16]]* %6, i64 0, i64 0
%53 = getelementptr inbounds [5 x i16], [5 x i16]* %52, i64 0, i64 0
%54 = getelementptr inbounds i16, i16* %53, i64 5
%55 = getelementptr inbounds i16, i16* %54, i64 2
%56 = load i16, i16* %55
%57 = sext i16 %56 to i32
%58 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([30 x i8], [30 x i8]* @.str.15, i64 0, i64 0), i32 %57)
ret void
}

LLVM IR (-O2):
@.str.1 = [19 x i8] c"sizeof(str1) = %u\0A\00"
@.str.2 = [19 x i8] c"sizeof(str2) = %u\0A\00"
@.str.3 = [19 x i8] c"sizeof(str3) = %u\0A\00"
@.str.4 = [19 x i8] c"sizeof(cPtr) = %u\0A\00"
@.str.6 = [19 x i8] c"sizeof(sArr) = %u\0A\00"
@.str.7 = [20 x i8] c"sizeof(sPtr1) = %u\0A\00"
@.str.8 = [21 x i8] c"sizeof(sArr2D) = %u\0A\00"
@.str.9 = [20 x i8] c"sizeof(sPtr2) = %u\0A\00"
@.str.10 = [21 x i8] c"sizeof(*sPtr2) = %u\0A\00"
@.str.11 = [20 x i8] c"sizeof(sPtr3) = %u\0A\00"
@.str.12 = [19 x i8] c"sArr2D[1][2] = %d\0A\00"
@.str.13 = [36 x i8] c"sPtr2[0][0] = %d, sPtr2[1][2] = %d\0A\00"
@.str.14 = [28 x i8] c"*(* (sArr2D + 1) + 2) = %d\0A\00"
@.str.15 = [30 x i8] c"*(*(sArr2D) + 1*5 + 2) = %d\0A\0A\00"
define void @trick3() {
%1 = tail call i32 (i8*, ...) @printf(i8* dereferenceable(1) getelementptr inbounds ([19 x i8], [19 x i8]* @.str.1, i64 0, i64 0), i64 5)
%2 = tail call i32 (i8*, ...) @printf(i8* dereferenceable(1) getelementptr inbounds ([19 x i8], [19 x i8]* @.str.2, i64 0, i64 0), i64 6)
%3 = tail call i32 (i8*, ...) @printf(i8* dereferenceable(1) getelementptr inbounds ([19 x i8], [19 x i8]* @.str.3, i64 0, i64 0), i64 8)
%4 = tail call i32 (i8*, ...) @printf(i8* dereferenceable(1) getelementptr inbounds ([19 x i8], [19 x i8]* @.str.4, i64 0, i64 0), i64 8)
%5 = tail call i32 @putchar(i32 10)
%6 = tail call i32 (i8*, ...) @printf(i8* dereferenceable(1) getelementptr inbounds ([19 x i8], [19 x i8]* @.str.6, i64 0, i64 0), i64 10)
%7 = tail call i32 (i8*, ...) @printf(i8* dereferenceable(1) getelementptr inbounds ([20 x i8], [20 x i8]* @.str.7, i64 0, i64 0), i64 8)
%8 = tail call i32 (i8*, ...) @printf(i8* dereferenceable(1) getelementptr inbounds ([21 x i8], [21 x i8]* @.str.8, i64 0, i64 0), i64 20)
%9 = tail call i32 (i8*, ...) @printf(i8* dereferenceable(1) getelementptr inbounds ([20 x i8], [20 x i8]* @.str.9, i64 0, i64 0), i64 8)
%10 = tail call i32 (i8*, ...) @printf(i8* dereferenceable(1) getelementptr inbounds ([21 x i8], [21 x i8]* @.str.10, i64 0, i64 0), i64 10)
%11 = tail call i32 (i8*, ...) @printf(i8* dereferenceable(1) getelementptr inbounds ([20 x i8], [20 x i8]* @.str.11, i64 0, i64 0), i64 40)
%12 = tail call i32 @putchar(i32 10)
%13 = tail call i32 (i8*, ...) @printf(i8* dereferenceable(1) getelementptr inbounds ([19 x i8], [19 x i8]* @.str.12, i64 0, i64 0), i32 8)
%14 = tail call i32 (i8*, ...) @printf(i8* dereferenceable(1) getelementptr inbounds ([36 x i8], [36 x i8]* @.str.13, i64 0, i64 0), i32 1, i32 8)
%15 = tail call i32 (i8*, ...) @printf(i8* dereferenceable(1) getelementptr inbounds ([28 x i8], [28 x i8]* @.str.14, i64 0, i64 0), i32 8)
%16 = tail call i32 (i8*, ...) @printf(i8* dereferenceable(1) getelementptr inbounds ([30 x i8], [30 x i8]* @.str.15, i64 0, i64 0), i32 8)
ret void
}