2012-12-14 44 views
4

在下面的代码片段中,主函数调用没有任何参数和圆括号的foo函数。奇怪的是,这个代码可以由gcc编译。我实际上检查了汇编代码,发现编译器忽略了这一行。所以我的问题是在哪种情况下使用这种代码?或者gcc的支持只是一个巧合,实际上它完全没用。通过objdump的甩不带参数和括号的调用函数

int foo(int a,int b) 
{ 
    return a+b; 
} 
int main() 
{ 
    foo;  // call foo without parameter and parenthesis 
    return 0; 
} 

它的汇编代码-d

00000000004004c0 <main>: 
    4004c0: 55      push %rbp 
    4004c1: 48 89 e5    mov %rsp,%rbp 
    4004c4: b8 00 00 00 00   mov $0x0,%eax 
    4004c9: 5d      pop %rbp 
    4004ca: c3      retq 
    4004cb: 0f 1f 44 00 00   nopl 0x0(%rax,%rax,1) 
+0

没有函数在没有括号的情况下被调用。但是,[REBOL编程语言](https://en.wikipedia.org/wiki/REBOL)实际上允许您在没有括号的情况下调用函数。 –

回答

1

foo是没有得到调用,它只是指(并没有分配到任何东西)。

6

评估表达式foo(给出函数的地址),并且结果被丢弃。如果没有()运算符,则不调用该函数。

+1

'foo'甚至没有评估。 'foo'只是源代码中一个可读的名字,它指向一个函数的地址。这个地址没有被调用,所以还没有任何“结果”丢弃 – Alexander

+0

@Alexander 123是一个C定义的表达式,foo也是如此。其实任何事物都是表达式,任何表达式都会被评估。 123评估为整数123,123L评估为长123,foo评估为功能地址。我同意评估不会在运行时发生,我明白你的意思。但是,从理论上讲,在编译时,人类可读的符号被评估并用其地址代替,然后被忽略(或者简单地优化为不存在)。所以答案是正确的。 – FrancescoMM

9

这是没有比拥有任何其他类型的表达式,而忽略它的价值,就像不同:

int main(void) 
{ 
    42; 
    return 0; 
} 

没有什么特别的,这是调用该函数,因为函数调用运营商()不正在使用。你所做的只是“计算”函数的地址,然后忽略它。

+0

那么这样做有什么意义呢?我遇到了一段代码,也做到这一点,不知道为什么。 –

+1

@JeffersonH​​udson我认为没有任何意义。任何理智的编译器都会将其编译为无,即它将被忽略,因为它没有副作用。它可能是调试的遗留物,或者只是一个编辑错误。 – unwind