2013-03-18 111 views
1

我有這樣的C代碼。在64位Linux系統上,結果是:4294967264而不是-32。 clang和gcc都會產生具有相同錯誤結果的二進制文件。 在該行的問題:va_arg 64位問題

*v = va_arg(args, long);
#include <stdio.h> 
#include <string.h> 
#include <stdarg.h> 

void setter(long *v, ...) 
{ 
     va_list args; 
     va_start(args, v); 
     *v = va_arg(args, long); 
     va_end(args); 
} 

int main() 
{ 
     long v = 0; 
     setter((long *) &v, -32); 
     printf("%ld\n", v); 
     return 0; 
} 

回答

4

你確實需要一個long傳遞給你的函數。你通過了int

setter(&v, -32L); 
+0

謝謝,完全忘了這個。 – brovko 2013-03-18 16:03:39

3

在x86_64架構上,long的大小爲64位。當你通過-32setter()時,它的類型是int,只有32位。如果您想要傳遞long,請明確投射它。例如:

setter((long *) &v, (long)-32); 
+0

-32L是一樣的,沒有演員。 – brovko 2013-03-18 16:09:57

1

小澄清:
如所述,在64位架構中,long是64位的。然而,這不是全部,因爲C/C++會自動進行一些轉換。在這裏,setter()函數接受一個指定的參數和零個或多個未指定的參數。 -32參數是其中一個未指定的參數,因此編譯器不知道實際上是否有long,並且保留了int(32位)。此外,還有一個額外的零被壓入堆棧以保持64位對齊。這將產生如上所述的打印結果。因此,您必須在此明確指定您需要long-32L(long) -32)。但是如果函數實際上被聲明爲void setter (long *v, long arg),那麼編譯器會知道第二個參數是long,並自動轉換爲int參數。