当我使用void时,内存会看到什么数据类型?

时间:2009-05-05 20:20:27

标签: c# c++

当我创建int类型的方法时,编译器会在内存中保留X个位数。那么如何看待虚空类型呢? void类型占用多少位/字节?

6 个答案:

答案 0 :(得分:13)

void类型不占用任何位。你不能声明一个void类型的变量。这样:

void a;

导致编译错误 void只是一个占位符,意思是“没有”一个返回void的函数返回什么,一个函数将void作为一个参数,不带任何参数。

但是,您可以声明void *:

类型的变量
void* a;

这只是声明一个指向任何东西的指针。作为任何指针,它采用指针类型的大小,即sizeof(void *),在32位系统中通常等于4。

答案 1 :(得分:3)

我认为您对编译器如何存储返回值的假设可能过于通用。返回值会发生什么情况取决于语言,类型和硬件。

可能有一个'返回寄存器'可以保存返回值,因此不会占用任何内存。 “返回寄存器”也可以根据返回的类型指向内存中分配的内容。

我不明白为什么返回void的函数会为返回值分配内存。

答案 2 :(得分:3)

在x86架构上(使用gcc 3.4.6),int函数的返回值存储在eax寄存器中。浮点数通过XMM寄存器或ST0返回。 [编辑:谢谢巴斯蒂安伦纳德!]

Void函数根本不会将任何东西放入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"

定义了f2:

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函数根本不返回任何内容。它要么单独留下返回寄存器,要么/或者什么都不丢弃(或进入)堆栈。

答案 3 :(得分:2)

函数返回void,调用者不期望任何返回值,也不需要分配任何内容。 void不是要返回的真实类型,它更多地表明编译器函数不返回任何内容。

在PC上,函数通过将它们放在特定的寄存器(int)中来返回像eax这样的简单值;编译器只需生成适当的代码即可检索此值。 (如果函数返回void,则编译器不会生成此类代码。)
在其他体系结构上,调用者可能会隐式传递一个指向int的参数,其中将返回值。

C和C ++标准没有规定这种低级别的东西。它可以由另一个标准指定,或者它可能只是一个惯例。

对于C#,我猜答案在于如何在CIL中获得返回值。

答案 4 :(得分:1)

C或C ++本身没有void类型(我对C#一无所知)。 void *是无类型指针。

这可能有所帮助:http://c-faq.com/ansi/voidparith.html

答案 5 :(得分:0)

它只是一个未定义的指针类型,因此大小是您正在创建它的系统上任何其他指针的大小。