这是LLVM中的错误吗?

时间:2017-06-03 11:33:36

标签: c clang llvm sizeof

我正在编译此代码(使用clang 3.4.2):

#include <stdlib.h>
#include <stdio.h>
#include <inttypes.h>

typedef struct __entry {
    char *name;
    int value;
} entry;

int main(int argv, char **argc) {
            printf("Size of entry: %lu\n", sizeof(entry));
        entry *entry = malloc(sizeof(entry));
        printf("entry is at %lu\n", (uint64_t) entry);
}

我收到了这个bitcode:

define i32 @main(i32 %argv, i8** %argc) #0 {
entry:
  %argv.addr = alloca i32, align 4
  %argc.addr = alloca i8**, align 8
  %entry1 = alloca %struct.__entry*, align 8
  store i32 %argv, i32* %argv.addr, align 4
  store i8** %argc, i8*** %argc.addr, align 8
  %call = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([20 x i8]* @.str, i32 0, i32 0), i64 16)
  %call2 = call noalias i8* @malloc(i64 8) #3
  %0 = bitcast i8* %call2 to %struct.__entry*
  store %struct.__entry* %0, %struct.__entry** %entry1, align 8
  %1 = load %struct.__entry** %entry1, align 8
  %2 = ptrtoint %struct.__entry* %1 to i64
  %call3 = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([17 x i8]* @.str1, i32 0, i32 0), i64 %2)
  ret i32 0
}

对printf的调用接收16作为参数(我期望在64位系统上有两个指针的结构)。但是,对malloc的调用收到8.在C中,它们都有相同的参数。发生了什么事?

1 个答案:

答案 0 :(得分:9)

sizeof的两次调用没有得到相同的论点!它看起来只是乍一看。

第一个sizeof(entry)指的是类型名称。

第二个sizeof(entry)引用本地指针变量。

定义变量后,您不能再引用代码块中的类型。

这意味着标题问题的答案是&#34;否 - LLVM遵循标准的要求&#34;。

一个小怪癖:第一个sizeof(entry)必须有括号,因为参数是类型名称。第二个sizeof(entry)可以写成sizeof entry,因为该参数是变量的名称而不是类型。这允许您确认第二次出现是指变量而不是类型。