2009-05-05 37 views
2

當我創建一個int類型的方法時,編譯器會在內存中保留X位。那麼如何看待一個void類型呢? void類型佔用多少位/字節?當我使用void時,內存會看到什麼數據類型?

+0

您是否在談論函數的返回值? – MStodd 2009-05-05 20:30:13

+2

沒有人讀過這個問題嗎?他說'int類型的方法'我假設他的意思是'返回int的方法'。他沒有問一個空指針佔用了多少空間。 請澄清。 – MStodd 2009-05-05 20:35:46

回答

13

void類型不佔用任何位。你不能聲明void類型的變量。這個:

void a; 

會導致編譯錯誤。
void只是一個佔位符,意思是「nothing」返回void的函數不返回任何內容,並且函數將void作爲參數,不帶任何參數。

但是你可以聲明void *類型的變量:

void* a; 

這只是聲明瞭一個指針可以指向任何東西都沒有。作爲任何指針,它需要指針類型的大小,即sizeof(void *),它通常在32位系統中等於4。

3

我想你所做的關於編譯器如何存儲返回值的假設可能太泛泛。返回值會發生什麼是由語言,類型和硬件決定的。

可能有一個'返回寄存器'可以保存返回值,因此不會佔用內存。 '返回寄存器'也可以指向基於返回類型的內存分配。

我不明白爲什麼返回void的函數會爲返回值分配內存。

1

在C或C++中本質上沒有void類型(我對C#一無所知)。 void *是一個無類型指針。

這可能會有所幫助:http://c-faq.com/ansi/voidparith.html

+0

我不認爲他在談論變量,而是函數簽名。 – MStodd 2009-05-05 20:31:37

+0

malloc返回一個void * ...這是一個通用指針,分配給調用的內存區域。在C中,從void *到其他類型指針的轉換是自動的。返回指針指向的內存大小是指定爲malloc參數的大小。 仍然沒有void數據類型。用於參數列表中,它指定該函數不帶任何參數。 – 2009-05-05 21:11:27

0

這只是一個未定義的指針類型,所以尺寸爲你創建它的系統上的任何其他指針的大小。

3

在x86架構(使用gcc 3.4.6)上,int函數的返回值存儲在eax寄存器中。浮點數字通過XMM寄存器或ST0返回。 [編輯:謝謝Bastien Leonard!]

無效函數根本不會將任何東西放入eax中並返回。

#include <stdio.h> 

int f1(void) 
{ 
    printf("f1\n"); 
    return 9.0f; 
} 
void f2(void) 
{ 
    printf("f2\n"); 
} 

double f3(void) 
{ 
    return 10.0; 
} 

int main(void) 
{ 
    int x = f1(); 
    f2(); 
    double y = f3(); 
    return 0; 
} 

建立用gcc -S來:

main: 
    pushl %ebp 
    movl %esp, %ebp 
    subl $24, %esp 
    andl $-16, %esp 
    movl $0, %eax 
    addl $15, %eax 
    addl $15, %eax 
    shrl $4, %eax 
    sall $4, %eax 
    subl %eax, %esp 
    call f1 
    movl %eax, -4(%ebp) 
    call f2 
    call f3 
    fstpl -16(%ebp) 
    movl $0, %eax 
    leave 
    ret 
    .size main, .-main 
    .section  .note.GNU-stack,"",@progbits 
    .ident "GCC: (GNU) 3.4.6" 

具有f定義:

f2: 
    pushl %ebp 
    movl %esp, %ebp 
    subl $8, %esp 
    subl $12, %esp 
    pushl $.LC1 
    call printf 
    addl $16, %esp 
    leave 
    ret 
    .size f2, .-f2 

和F1定義:

f1: 
    pushl %ebp 
    movl %esp, %ebp 
    subl $8, %esp 
    subl $12, %esp 
    pushl $.LC0 
    call printf 
    addl $16, %esp 
    movl $9, %eax 
    leave 
    ret 

如果其他人會從不同的代碼不同版本的gcc,這將是有趣的看到XD(也許在其他情況下int函數返回堆棧...)

我會想象,在所有的實現中,儘管一個void函數不會返回任何內容。它可以單獨退出寄存器和/或將任何東西放入(或放入)堆棧中。

2

該函數返回void,調用者不期望任何返回值,也不需要分配任何東西。 void不是要返回的實際類型,它更多地表示編譯器該函數不返回任何內容。

在PC上,函數通過將它們放置在特定的寄存器(eax)中返回簡單的值,如int;編譯器只是生成適當的代碼來檢索這個值。 (如果函數返回void,那麼編譯器不會生成這種類型的代碼。)
在其他體系結構上,調用者可能會隱式傳遞指向返回值將放置在其中的參數的參數。

這種低級別的東西不是由C和C++標準規定的。它可能由另一個標準規定,或者它可能只是一個約定。

對於C#,我想答案在於如何在CIL中獲得返回值。

相關問題