【发布时间】:2017-12-05 04:20:39
【问题描述】:
我知道void *function() 是指向函数的指针,但我不知道它们的工作方式有何不同以及我们何时使用void *function()?
我在组装方面做了一些研究,以比较它们在幕后的工作方式,看起来它们是一样的。
这是c++代码:
void *bar(){
std::cout << "bar" << std::endl;
}
void foo(){
std::cout << "foo" << std::endl;
}
int main(void){
foo();
bar();
return 0;
}
这是我从 objdump 收到的汇编指令
void *bar(){
400846: 55 push %rbp
400847: 48 89 e5 mov %rsp,%rbp
std::cout << "bar" << std::endl;
40084a: be 84 09 40 00 mov $0x400984,%esi
40084f: bf 60 10 60 00 mov $0x601060,%edi
400854: e8 b7 fe ff ff callq 400710 <_ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc@plt>
400859: be 30 07 40 00 mov $0x400730,%esi
40085e: 48 89 c7 mov %rax,%rdi
400861: e8 ba fe ff ff callq 400720 <_ZNSolsEPFRSoS_E@plt>
}
400866: 90 nop
400867: 5d pop %rbp
400868: c3 retq
0000000000400869 <_Z3foov>:
void foo(){
400869: 55 push %rbp
40086a: 48 89 e5 mov %rsp,%rbp
std::cout << "foo" << std::endl;
40086d: be 88 09 40 00 mov $0x400988,%esi
400872: bf 60 10 60 00 mov $0x601060,%edi
400877: e8 94 fe ff ff callq 400710 <_ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc@plt>
40087c: be 30 07 40 00 mov $0x400730,%esi
400881: 48 89 c7 mov %rax,%rdi
400884: e8 97 fe ff ff callq 400720 <_ZNSolsEPFRSoS_E@plt>
}
400889: 90 nop
40088a: 5d pop %rbp
40088b: c3 retq
000000000040088c <main>:
int main(void){
40088c: 55 push %rbp
40088d: 48 89 e5 mov %rsp,%rbp
foo();
400890: e8 d4 ff ff ff callq 400869 <_Z3foov>
bar();
400895: e8 ac ff ff ff callq 400846 <_Z3barv>
return 0;
40089a: b8 00 00 00 00 mov $0x0,%eax
}
40089f: 5d pop %rbp
4008a0: c3 retq
【问题讨论】:
-
bar返回一个void指针,而foo什么也不返回。如果这本身还不够不同,那么您需要在继续之前阅读一本好书。 -
哦,如果你声明一个函数返回一些东西,你必须返回一些东西或者你有未定义的行为。
-
你应该得到类似
warning: control reaches end of non-void function [-Wreturn-type] -
@DuyVu -Wall -Wextra -Werror -pedantic 适用于任何 gcc/clang 编译器链。
-
你的测试没有任何意义,因为你什么也没返回。