void test_zero_object(void) {
  struct {
    int foo;
    double bar;
  } objects[10];
  for (int i = 0; i < ((int)((sizeof(objects) / sizeof(*(objects))) /
                             !(sizeof(objects) % sizeof(*(objects)))));
       ++i) {
    objects[i].foo = 5 + i * i;
    objects[i].bar = 3.7 * objects[i].foo;
  }
  az_zero_memory_((&objects[7]), sizeof(*(&objects[7])));
  _expect_int_eq(41, objects[6].foo,
                 "41"
                 " == "
                 "objects[6].foo");
  _expect_approx(151.7, objects[6].bar,
                 "151.7"
                 " == "
                 "objects[6].bar");
  _expect_int_eq(0, objects[7].foo,
                 "0"
                 " == "
                 "objects[7].foo");
  _expect_approx(0.0, objects[7].bar,
                 "0.0"
                 " == "
                 "objects[7].bar");
  _expect_int_eq(69, objects[8].foo,
                 "69"
                 " == "
                 "objects[8].foo");
  _expect_approx(255.3, objects[8].bar,
                 "255.3"
                 " == "
                 "objects[8].bar");
}


x86 assembly (clang, -O0):
<test_zero_object>:
push   %rbp
mov    %rsp,%rbp
sub    $0xb0,%rsp
movl   $0x0,-0xa4(%rbp)
cmpl   $0xa,-0xa4(%rbp)
jge    11cc <test_zero_object+0x9c>
mov    -0xa4(%rbp),%ecx
imul   -0xa4(%rbp),%ecx
add    $0x5,%ecx
movslq -0xa4(%rbp),%rdx
lea    -0xa0(%rbp),%rax
shl    $0x4,%rdx
add    %rdx,%rax
mov    %ecx,(%rax)
movslq -0xa4(%rbp),%rcx
lea    -0xa0(%rbp),%rax
shl    $0x4,%rcx
add    %rcx,%rax
cvtsi2sdl (%rax),%xmm1
movsd  0xe76(%rip),%xmm0
mulsd  %xmm1,%xmm0
movslq -0xa4(%rbp),%rcx
lea    -0xa0(%rbp),%rax
shl    $0x4,%rcx
add    %rcx,%rax
movsd  %xmm0,0x8(%rax)
mov    -0xa4(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0xa4(%rbp)
jmp    1145 <test_zero_object+0x15>
lea    -0xa0(%rbp),%rdi
add    $0x70,%rdi
mov    $0x10,%esi
mov    $0x0,%al
call   1050 <az_zero_memory_@plt>
mov    -0x40(%rbp),%esi
mov    $0x29,%edi
lea    0xe26(%rip),%rdx
mov    $0x0,%al
call   1030 <_expect_int_eq@plt>
movsd  -0x38(%rbp),%xmm1
movsd  0xe02(%rip),%xmm0
lea    0xe20(%rip),%rdi
mov    $0x2,%al
call   1040 <_expect_approx@plt>
mov    -0x30(%rbp),%esi
xor    %edi,%edi
lea    0xe25(%rip),%rdx
mov    $0x0,%al
call   1030 <_expect_int_eq@plt>
movsd  -0x28(%rbp),%xmm1
xorps  %xmm0,%xmm0
lea    0xe23(%rip),%rdi
mov    $0x2,%al
call   1040 <_expect_approx@plt>
mov    -0x20(%rbp),%esi
mov    $0x45,%edi
lea    0xe23(%rip),%rdx
mov    $0x0,%al
call   1030 <_expect_int_eq@plt>
movsd  -0x18(%rbp),%xmm1
movsd  0xda0(%rip),%xmm0
lea    0xe1d(%rip),%rdi
mov    $0x2,%al
call   1040 <_expect_approx@plt>
add    $0xb0,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<test_zero_object>:
sub    $0xa8,%rsp
movl   $0x5,(%rsp)
movabs $0x4032800000000000,%rax
80 32 40
mov    %rax,0x8(%rsp)
movl   $0x6,0x10(%rsp)
movabs $0x4036333333333334,%rax
33 36 40
mov    %rax,0x18(%rsp)
movl   $0x9,0x20(%rsp)
movabs $0x4040a66666666667,%rax
a6 40 40
mov    %rax,0x28(%rsp)
movl   $0xe,0x30(%rsp)
movabs $0x4049e66666666667,%rax
e6 49 40
mov    %rax,0x38(%rsp)
movl   $0x15,0x40(%rsp)
movabs $0x40536ccccccccccd,%rax
6c 53 40
mov    %rax,0x48(%rsp)
movl   $0x1e,0x50(%rsp)
movabs $0x405bc00000000000,%rax
c0 5b 40
mov    %rax,0x58(%rsp)
movl   $0x29,0x60(%rsp)
movabs $0x4062f66666666667,%rax
f6 62 40
mov    %rax,0x68(%rsp)
lea    0x70(%rsp),%rdi
movl   $0x36,0x70(%rsp)
movabs $0x4068f9999999999a,%rax
f9 68 40
mov    %rax,0x78(%rsp)
movl   $0x45,0x80(%rsp)
movabs $0x406fe9999999999a,%rax
e9 6f 40
mov    %rax,0x88(%rsp)
movl   $0x56,0x90(%rsp)
movabs $0x4073e33333333333,%rax
e3 73 40
mov    %rax,0x98(%rsp)
mov    $0x10,%esi
xor    %eax,%eax
call   1050 <az_zero_memory_@plt>
mov    0x60(%rsp),%esi
lea    0xdcc(%rip),%rdx
mov    $0x29,%edi
xor    %eax,%eax
call   1030 <_expect_int_eq@plt>
movsd  0x68(%rsp),%xmm1
lea    0xdc8(%rip),%rdi
movsd  0xd9b(%rip),%xmm0
mov    $0x2,%al
call   1040 <_expect_approx@plt>
mov    0x70(%rsp),%esi
lea    0xdc6(%rip),%rdx
xor    %edi,%edi
xor    %eax,%eax
call   1030 <_expect_int_eq@plt>
movsd  0x78(%rsp),%xmm1
lea    0xdc4(%rip),%rdi
xorps  %xmm0,%xmm0
mov    $0x2,%al
call   1040 <_expect_approx@plt>
mov    0x80(%rsp),%esi
lea    0xdc2(%rip),%rdx
mov    $0x45,%edi
xor    %eax,%eax
call   1030 <_expect_int_eq@plt>
movsd  0x88(%rsp),%xmm1
lea    0xdbb(%rip),%rdi
movsd  0xd3f(%rip),%xmm0
mov    $0x2,%al
call   1040 <_expect_approx@plt>
add    $0xa8,%rsp
ret

LLVM IR (-O0):
%struct.anon = type { i32, double }
@.str = [21 x i8] c"41 == objects[6].foo\00"
@.str.1 = [24 x i8] c"151.7 == objects[6].bar\00"
@.str.2 = [20 x i8] c"0 == objects[7].foo\00"
@.str.3 = [22 x i8] c"0.0 == objects[7].bar\00"
@.str.4 = [21 x i8] c"69 == objects[8].foo\00"
@.str.5 = [24 x i8] c"255.3 == objects[8].bar\00"
define void @test_zero_object() {
%1 = alloca [10 x %struct.anon]
%2 = alloca i32
store i32 0, i32* %2
br label %3
3: ; preds = %26, %0
%4 = load i32, i32* %2
%5 = icmp slt i32 %4, 10
br i1 %5, label %6, label %29
6: ; preds = %3
%7 = load i32, i32* %2
%8 = load i32, i32* %2
%9 = mul nsw i32 %7, %8
%10 = add nsw i32 5, %9
%11 = load i32, i32* %2
%12 = sext i32 %11 to i64
%13 = getelementptr inbounds [10 x %struct.anon], [10 x %struct.anon]* %1, i64 0, i64 %12
%14 = getelementptr inbounds %struct.anon, %struct.anon* %13, i32 0, i32 0
store i32 %10, i32* %14
%15 = load i32, i32* %2
%16 = sext i32 %15 to i64
%17 = getelementptr inbounds [10 x %struct.anon], [10 x %struct.anon]* %1, i64 0, i64 %16
%18 = getelementptr inbounds %struct.anon, %struct.anon* %17, i32 0, i32 0
%19 = load i32, i32* %18
%20 = sitofp i32 %19 to double
%21 = fmul double 3.700000e+00, %20
%22 = load i32, i32* %2
%23 = sext i32 %22 to i64
%24 = getelementptr inbounds [10 x %struct.anon], [10 x %struct.anon]* %1, i64 0, i64 %23
%25 = getelementptr inbounds %struct.anon, %struct.anon* %24, i32 0, i32 1
store double %21, double* %25
br label %26
26: ; preds = %6
%27 = load i32, i32* %2
%28 = add nsw i32 %27, 1
store i32 %28, i32* %2
br label %3
29: ; preds = %3
%30 = getelementptr inbounds [10 x %struct.anon], [10 x %struct.anon]* %1, i64 0, i64 7
%31 = call i32 (%struct.anon*, i64, ...) bitcast (i32 (...)* @az_zero_memory_ to i32 (%struct.anon*, i64, ...)*)(%struct.anon* %30, i64 16)
%32 = getelementptr inbounds [10 x %struct.anon], [10 x %struct.anon]* %1, i64 0, i64 6
%33 = getelementptr inbounds %struct.anon, %struct.anon* %32, i32 0, i32 0
%34 = load i32, i32* %33
%35 = call i32 (i32, i32, i8*, ...) bitcast (i32 (...)* @_expect_int_eq to i32 (i32, i32, i8*, ...)*)(i32 41, i32 %34, i8* getelementptr inbounds ([21 x i8], [21 x i8]* @.str, i64 0, i64 0))
%36 = getelementptr inbounds [10 x %struct.anon], [10 x %struct.anon]* %1, i64 0, i64 6
%37 = getelementptr inbounds %struct.anon, %struct.anon* %36, i32 0, i32 1
%38 = load double, double* %37
%39 = call i32 (double, double, i8*, ...) bitcast (i32 (...)* @_expect_approx to i32 (double, double, i8*, ...)*)(double 1.517000e+02, double %38, i8* getelementptr inbounds ([24 x i8], [24 x i8]* @.str.1, i64 0, i64 0))
%40 = getelementptr inbounds [10 x %struct.anon], [10 x %struct.anon]* %1, i64 0, i64 7
%41 = getelementptr inbounds %struct.anon, %struct.anon* %40, i32 0, i32 0
%42 = load i32, i32* %41
%43 = call i32 (i32, i32, i8*, ...) bitcast (i32 (...)* @_expect_int_eq to i32 (i32, i32, i8*, ...)*)(i32 0, i32 %42, i8* getelementptr inbounds ([20 x i8], [20 x i8]* @.str.2, i64 0, i64 0))
%44 = getelementptr inbounds [10 x %struct.anon], [10 x %struct.anon]* %1, i64 0, i64 7
%45 = getelementptr inbounds %struct.anon, %struct.anon* %44, i32 0, i32 1
%46 = load double, double* %45
%47 = call i32 (double, double, i8*, ...) bitcast (i32 (...)* @_expect_approx to i32 (double, double, i8*, ...)*)(double 0.000000e+00, double %46, i8* getelementptr inbounds ([22 x i8], [22 x i8]* @.str.3, i64 0, i64 0))
%48 = getelementptr inbounds [10 x %struct.anon], [10 x %struct.anon]* %1, i64 0, i64 8
%49 = getelementptr inbounds %struct.anon, %struct.anon* %48, i32 0, i32 0
%50 = load i32, i32* %49
%51 = call i32 (i32, i32, i8*, ...) bitcast (i32 (...)* @_expect_int_eq to i32 (i32, i32, i8*, ...)*)(i32 69, i32 %50, i8* getelementptr inbounds ([21 x i8], [21 x i8]* @.str.4, i64 0, i64 0))
%52 = getelementptr inbounds [10 x %struct.anon], [10 x %struct.anon]* %1, i64 0, i64 8
%53 = getelementptr inbounds %struct.anon, %struct.anon* %52, i32 0, i32 1
%54 = load double, double* %53
%55 = call i32 (double, double, i8*, ...) bitcast (i32 (...)* @_expect_approx to i32 (double, double, i8*, ...)*)(double 2.553000e+02, double %54, i8* getelementptr inbounds ([24 x i8], [24 x i8]* @.str.5, i64 0, i64 0))
ret void
}

LLVM IR (-O2):
%struct.anon = type { i32, double }
@.str = [21 x i8] c"41 == objects[6].foo\00"
@.str.1 = [24 x i8] c"151.7 == objects[6].bar\00"
@.str.2 = [20 x i8] c"0 == objects[7].foo\00"
@.str.3 = [22 x i8] c"0.0 == objects[7].bar\00"
@.str.4 = [21 x i8] c"69 == objects[8].foo\00"
@.str.5 = [24 x i8] c"255.3 == objects[8].bar\00"
define void @test_zero_object() {
%1 = alloca [10 x %struct.anon]
%2 = bitcast [10 x %struct.anon]* %1 to i8*
%3 = getelementptr inbounds [10 x %struct.anon], [10 x %struct.anon]* %1, i64 0, i64 0, i32 0
store i32 5, i32* %3
%4 = getelementptr inbounds [10 x %struct.anon], [10 x %struct.anon]* %1, i64 0, i64 0, i32 1
store double 1.850000e+01, double* %4
%5 = getelementptr inbounds [10 x %struct.anon], [10 x %struct.anon]* %1, i64 0, i64 1, i32 0
store i32 6, i32* %5
%6 = getelementptr inbounds [10 x %struct.anon], [10 x %struct.anon]* %1, i64 0, i64 1, i32 1
store double 0x4036333333333334, double* %6
%7 = getelementptr inbounds [10 x %struct.anon], [10 x %struct.anon]* %1, i64 0, i64 2, i32 0
store i32 9, i32* %7
%8 = getelementptr inbounds [10 x %struct.anon], [10 x %struct.anon]* %1, i64 0, i64 2, i32 1
store double 0x4040A66666666667, double* %8
%9 = getelementptr inbounds [10 x %struct.anon], [10 x %struct.anon]* %1, i64 0, i64 3, i32 0
store i32 14, i32* %9
%10 = getelementptr inbounds [10 x %struct.anon], [10 x %struct.anon]* %1, i64 0, i64 3, i32 1
store double 0x4049E66666666667, double* %10
%11 = getelementptr inbounds [10 x %struct.anon], [10 x %struct.anon]* %1, i64 0, i64 4, i32 0
store i32 21, i32* %11
%12 = getelementptr inbounds [10 x %struct.anon], [10 x %struct.anon]* %1, i64 0, i64 4, i32 1
store double 7.770000e+01, double* %12
%13 = getelementptr inbounds [10 x %struct.anon], [10 x %struct.anon]* %1, i64 0, i64 5, i32 0
store i32 30, i32* %13
%14 = getelementptr inbounds [10 x %struct.anon], [10 x %struct.anon]* %1, i64 0, i64 5, i32 1
store double 1.110000e+02, double* %14
%15 = getelementptr inbounds [10 x %struct.anon], [10 x %struct.anon]* %1, i64 0, i64 6, i32 0
store i32 41, i32* %15
%16 = getelementptr inbounds [10 x %struct.anon], [10 x %struct.anon]* %1, i64 0, i64 6, i32 1
store double 0x4062F66666666667, double* %16
%17 = getelementptr inbounds [10 x %struct.anon], [10 x %struct.anon]* %1, i64 0, i64 7, i32 0
store i32 54, i32* %17
%18 = getelementptr inbounds [10 x %struct.anon], [10 x %struct.anon]* %1, i64 0, i64 7, i32 1
store double 1.998000e+02, double* %18
%19 = getelementptr inbounds [10 x %struct.anon], [10 x %struct.anon]* %1, i64 0, i64 8, i32 0
store i32 69, i32* %19
%20 = getelementptr inbounds [10 x %struct.anon], [10 x %struct.anon]* %1, i64 0, i64 8, i32 1
store double 2.553000e+02, double* %20
%21 = getelementptr inbounds [10 x %struct.anon], [10 x %struct.anon]* %1, i64 0, i64 9, i32 0
store i32 86, i32* %21
%22 = getelementptr inbounds [10 x %struct.anon], [10 x %struct.anon]* %1, i64 0, i64 9, i32 1
store double 3.182000e+02, double* %22
%23 = getelementptr inbounds [10 x %struct.anon], [10 x %struct.anon]* %1, i64 0, i64 7
%24 = call i32 (%struct.anon*, i64, ...) bitcast (i32 (...)* @az_zero_memory_ to i32 (%struct.anon*, i64, ...)*)(%struct.anon* %23, i64 16)
%25 = load i32, i32* %15
%26 = call i32 (i32, i32, i8*, ...) bitcast (i32 (...)* @_expect_int_eq to i32 (i32, i32, i8*, ...)*)(i32 41, i32 %25, i8* getelementptr inbounds ([21 x i8], [21 x i8]* @.str, i64 0, i64 0))
%27 = load double, double* %16
%28 = call i32 (double, double, i8*, ...) bitcast (i32 (...)* @_expect_approx to i32 (double, double, i8*, ...)*)(double 1.517000e+02, double %27, i8* getelementptr inbounds ([24 x i8], [24 x i8]* @.str.1, i64 0, i64 0))
%29 = getelementptr inbounds %struct.anon, %struct.anon* %23, i64 0, i32 0
%30 = load i32, i32* %29
%31 = call i32 (i32, i32, i8*, ...) bitcast (i32 (...)* @_expect_int_eq to i32 (i32, i32, i8*, ...)*)(i32 0, i32 %30, i8* getelementptr inbounds ([20 x i8], [20 x i8]* @.str.2, i64 0, i64 0))
%32 = load double, double* %18
%33 = call i32 (double, double, i8*, ...) bitcast (i32 (...)* @_expect_approx to i32 (double, double, i8*, ...)*)(double 0.000000e+00, double %32, i8* getelementptr inbounds ([22 x i8], [22 x i8]* @.str.3, i64 0, i64 0))
%34 = load i32, i32* %19
%35 = call i32 (i32, i32, i8*, ...) bitcast (i32 (...)* @_expect_int_eq to i32 (i32, i32, i8*, ...)*)(i32 69, i32 %34, i8* getelementptr inbounds ([21 x i8], [21 x i8]* @.str.4, i64 0, i64 0))
%36 = load double, double* %20
%37 = call i32 (double, double, i8*, ...) bitcast (i32 (...)* @_expect_approx to i32 (double, double, i8*, ...)*)(double 2.553000e+02, double %36, i8* getelementptr inbounds ([24 x i8], [24 x i8]* @.str.5, i64 0, i64 0))
ret void
}