const char *json_error_string(int err) {
  const char *errors[] = {"unknown error while parsing JSON",
                          "non-whitespace when expecting object start",
                          "non-whitespace when expecting attribute start",
                          "unknown attribute name",
                          "saw [ when not expecting array",
                          "array element specified, but no [",
                          "string value too long",
                          "garbage while expecting comma or } or ]",
                          "didn't find expected array start",
                          "too many array elements",
                          "garbage while expecting array comma",
                          "unsupported array element type",
                          "error during string parsing",
                          "strings in parallel arrays are not supported",
                          "invalid enumerated value",
                          "saw quoted value when expecting non-string",
                          "didn't see quoted value when expecting string",
                          "error while parsing a numerical argument",
                          "unexpected null value or attribute pointer"};
  if (err <= 0 || err >= (int)(sizeof(errors) / sizeof(errors[0])))
    return errors[0];
  else
    return errors[err];
}


x86 assembly (clang, -O0):
<json_error_string>:
push   %rbp
mov    %rsp,%rbp
sub    $0xb0,%rsp
mov    %edi,-0xc(%rbp)
lea    -0xb0(%rbp),%rdi
lea    0x2c54(%rip),%rsi
mov    $0x98,%edx
call   1030 <memcpy@plt>
cmpl   $0x0,-0xc(%rbp)
jle    114a <json_error_string+0x3a>
cmpl   $0x13,-0xc(%rbp)
jl     115a <json_error_string+0x4a>
mov    -0xb0(%rbp),%rax
mov    %rax,-0x8(%rbp)
jmp    116a <json_error_string+0x5a>
movslq -0xc(%rbp),%rax
mov    -0xb0(%rbp,%rax,8),%rax
ff
mov    %rax,-0x8(%rbp)
mov    -0x8(%rbp),%rax
add    $0xb0,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<json_error_string>:
lea    -0x13(%rdi),%eax
cmp    $0xffffffee,%eax
movslq %edi,%rax
lea    0x2ca0(%rip),%rcx
lea    (%rcx,%rax,8),%rax
cmovb  %rcx,%rax
mov    (%rax),%rax
ret

LLVM IR (-O0):
@.str = [33 x i8] c"unknown error while parsing JSON\00"
@.str.1 = [43 x i8] c"non-whitespace when expecting object start\00"
@.str.2 = [46 x i8] c"non-whitespace when expecting attribute start\00"
@.str.3 = [23 x i8] c"unknown attribute name\00"
@.str.4 = [31 x i8] c"saw [ when not expecting array\00"
@.str.5 = [34 x i8] c"array element specified, but no [\00"
@.str.6 = [22 x i8] c"string value too long\00"
@.str.7 = [40 x i8] c"garbage while expecting comma or } or ]\00"
@.str.8 = [33 x i8] c"didn't find expected array start\00"
@.str.9 = [24 x i8] c"too many array elements\00"
@.str.10 = [36 x i8] c"garbage while expecting array comma\00"
@.str.11 = [31 x i8] c"unsupported array element type\00"
@.str.12 = [28 x i8] c"error during string parsing\00"
@.str.13 = [45 x i8] c"strings in parallel arrays are not supported\00"
@.str.14 = [25 x i8] c"invalid enumerated value\00"
@.str.15 = [43 x i8] c"saw quoted value when expecting non-string\00"
@.str.16 = [46 x i8] c"didn't see quoted value when expecting string\00"
@.str.17 = [41 x i8] c"error while parsing a numerical argument\00"
@.str.18 = [43 x i8] c"unexpected null value or attribute pointer\00"
@__const.json_error_string.errors = [19 x i8*] [i8* getelementptr inbounds ([33 x i8], [33 x i8]* @.str, i32 0, i32 0), i8* getelementptr inbounds ([43 x i8], [43 x i8]* @.str.1, i32 0, i32 0), i8* getelementptr inbounds ([46 x i8], [46 x i8]* @.str.2, i32 0, i32 0), i8* getelementptr inbounds ([23 x i8], [23 x i8]* @.str.3, i32 0, i32 0), i8* getelementptr inbounds ([31 x i8], [31 x i8]* @.str.4, i32 0, i32 0), i8* getelementptr inbounds ([34 x i8], [34 x i8]* @.str.5, i32 0, i32 0), i8* getelementptr inbounds ([22 x i8], [22 x i8]* @.str.6, i32 0, i32 0), i8* getelementptr inbounds ([40 x i8], [40 x i8]* @.str.7, i32 0, i32 0), i8* getelementptr inbounds ([33 x i8], [33 x i8]* @.str.8, i32 0, i32 0), i8* getelementptr inbounds ([24 x i8], [24 x i8]* @.str.9, i32 0, i32 0), i8* getelementptr inbounds ([36 x i8], [36 x i8]* @.str.10, i32 0, i32 0), i8* getelementptr inbounds ([31 x i8], [31 x i8]* @.str.11, i32 0, i32 0), i8* getelementptr inbounds ([28 x i8], [28 x i8]* @.str.12, i32 0, i32 0), i8* getelementptr inbounds ([45 x i8], [45 x i8]* @.str.13, i32 0, i32 0), i8* getelementptr inbounds ([25 x i8], [25 x i8]* @.str.14, i32 0, i32 0), i8* getelementptr inbounds ([43 x i8], [43 x i8]* @.str.15, i32 0, i32 0), i8* getelementptr inbounds ([46 x i8], [46 x i8]* @.str.16, i32 0, i32 0), i8* getelementptr inbounds ([41 x i8], [41 x i8]* @.str.17, i32 0, i32 0), i8* getelementptr inbounds ([43 x i8], [43 x i8]* @.str.18, i32 0, i32 0)]
define i8* @json_error_string(i32 %0) {
%2 = alloca i8*
%3 = alloca i32
%4 = alloca [19 x i8*]
store i32 %0, i32* %3
%5 = bitcast [19 x i8*]* %4 to i8*
%6 = load i32, i32* %3
%7 = icmp sle i32 %6, 0
br i1 %7, label %11, label %8
8: ; preds = %1
%9 = load i32, i32* %3
%10 = icmp sge i32 %9, 19
br i1 %10, label %11, label %14
11: ; preds = %8, %1
%12 = getelementptr inbounds [19 x i8*], [19 x i8*]* %4, i64 0, i64 0
%13 = load i8*, i8** %12
store i8* %13, i8** %2
br label %19
14: ; preds = %8
%15 = load i32, i32* %3
%16 = sext i32 %15 to i64
%17 = getelementptr inbounds [19 x i8*], [19 x i8*]* %4, i64 0, i64 %16
%18 = load i8*, i8** %17
store i8* %18, i8** %2
br label %19
19: ; preds = %14, %11
%20 = load i8*, i8** %2
ret i8* %20
}

LLVM IR (-O2):
@.str = [33 x i8] c"unknown error while parsing JSON\00"
@.str.1 = [43 x i8] c"non-whitespace when expecting object start\00"
@.str.2 = [46 x i8] c"non-whitespace when expecting attribute start\00"
@.str.3 = [23 x i8] c"unknown attribute name\00"
@.str.4 = [31 x i8] c"saw [ when not expecting array\00"
@.str.5 = [34 x i8] c"array element specified, but no [\00"
@.str.6 = [22 x i8] c"string value too long\00"
@.str.7 = [40 x i8] c"garbage while expecting comma or } or ]\00"
@.str.8 = [33 x i8] c"didn't find expected array start\00"
@.str.9 = [24 x i8] c"too many array elements\00"
@.str.10 = [36 x i8] c"garbage while expecting array comma\00"
@.str.11 = [31 x i8] c"unsupported array element type\00"
@.str.12 = [28 x i8] c"error during string parsing\00"
@.str.13 = [45 x i8] c"strings in parallel arrays are not supported\00"
@.str.14 = [25 x i8] c"invalid enumerated value\00"
@.str.15 = [43 x i8] c"saw quoted value when expecting non-string\00"
@.str.16 = [46 x i8] c"didn't see quoted value when expecting string\00"
@.str.17 = [41 x i8] c"error while parsing a numerical argument\00"
@.str.18 = [43 x i8] c"unexpected null value or attribute pointer\00"
@__const.json_error_string.errors = [19 x i8*] [i8* getelementptr inbounds ([33 x i8], [33 x i8]* @.str, i32 0, i32 0), i8* getelementptr inbounds ([43 x i8], [43 x i8]* @.str.1, i32 0, i32 0), i8* getelementptr inbounds ([46 x i8], [46 x i8]* @.str.2, i32 0, i32 0), i8* getelementptr inbounds ([23 x i8], [23 x i8]* @.str.3, i32 0, i32 0), i8* getelementptr inbounds ([31 x i8], [31 x i8]* @.str.4, i32 0, i32 0), i8* getelementptr inbounds ([34 x i8], [34 x i8]* @.str.5, i32 0, i32 0), i8* getelementptr inbounds ([22 x i8], [22 x i8]* @.str.6, i32 0, i32 0), i8* getelementptr inbounds ([40 x i8], [40 x i8]* @.str.7, i32 0, i32 0), i8* getelementptr inbounds ([33 x i8], [33 x i8]* @.str.8, i32 0, i32 0), i8* getelementptr inbounds ([24 x i8], [24 x i8]* @.str.9, i32 0, i32 0), i8* getelementptr inbounds ([36 x i8], [36 x i8]* @.str.10, i32 0, i32 0), i8* getelementptr inbounds ([31 x i8], [31 x i8]* @.str.11, i32 0, i32 0), i8* getelementptr inbounds ([28 x i8], [28 x i8]* @.str.12, i32 0, i32 0), i8* getelementptr inbounds ([45 x i8], [45 x i8]* @.str.13, i32 0, i32 0), i8* getelementptr inbounds ([25 x i8], [25 x i8]* @.str.14, i32 0, i32 0), i8* getelementptr inbounds ([43 x i8], [43 x i8]* @.str.15, i32 0, i32 0), i8* getelementptr inbounds ([46 x i8], [46 x i8]* @.str.16, i32 0, i32 0), i8* getelementptr inbounds ([41 x i8], [41 x i8]* @.str.17, i32 0, i32 0), i8* getelementptr inbounds ([43 x i8], [43 x i8]* @.str.18, i32 0, i32 0)]
define i8* @json_error_string(i32 %0) {
%2 = add i32 %0, -19
%3 = icmp ult i32 %2, -18
%4 = sext i32 %0 to i64
%5 = getelementptr inbounds [19 x i8*], [19 x i8*]* @__const.json_error_string.errors, i64 0, i64 %4
%6 = select i1 %3, i8** getelementptr inbounds ([19 x i8*], [19 x i8*]* @__const.json_error_string.errors, i64 0, i64 0), i8** %5
%7 = load i8*, i8** %6
ret i8* %7
}