2017-06-03 74 views
-1

我編譯該代碼(使用鐺3.4.2):這是LLVM中的錯誤嗎?

#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); 
} 

和我收到此位碼:

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

程序運行時是否打印正確的值? – EOF

+1

您的代碼調用未定義的行爲。 – Stargateur

+2

該錯誤爲類型和對象重載了'entry'標識符。 – Jens

回答

9

sizeof的兩個調用沒有得到相同的論據!它看起來只是乍一看。

第一個sizeof(entry)指的是類型名稱。

第二個sizeof(entry)引用本地指針變量。

定義變量後,不能再引用代碼塊中的類型。

這意味着標題問題的答案是「否 - LLVM符合標準的要求」。

一個小小的怪癖:第一個sizeof(entry)必須有括號,因爲該參數是一個類型名稱。第二個sizeof(entry)可以寫成sizeof entry,因爲這個參數是一個變量的名稱而不是一個類型。這允許您確認第二次出現是指變量而不是類型。

+0

arrgh!多麼愚蠢的錯字。 – Alex