[编译环境][gcc]在函数中定义函数

来源:互联网 发布:视频赚钱软件 编辑:程序博客网 时间:2024/06/05 07:38

代码和执行

#include <stdio.h>void fun();int main(void){    {        void fun()        {            printf("Message from main!\n");        }        fun();    }    fun();    return 0;}void fun(){    printf("Message from fun!\n");}

执行结果如下:

Message from main!
Message from fun!

反汇编目标文件结果如下:

test.o:     文件格式 elf64-x86-64Disassembly of section .text:0000000000000000 <fun.2287>:   0:   55                      push   %rbp   1:   48 89 e5                mov    %rsp,%rbp   4:   48 83 ec 10             sub    $0x10,%rsp   8:   4c 89 55 f8             mov    %r10,-0x8(%rbp)   c:   bf 00 00 00 00          mov    $0x0,%edi  11:   e8 00 00 00 00          callq  16 <fun.2287+0x16>  16:   90                      nop  17:   c9                      leaveq   18:   c3                      retq   0000000000000019 <main>:  19:   55                      push   %rbp  1a:   48 89 e5                mov    %rsp,%rbp  1d:   48 83 ec 10             sub    $0x10,%rsp  21:   64 48 8b 04 25 28 00    mov    %fs:0x28,%rax  28:   00 00   2a:   48 89 45 f8             mov    %rax,-0x8(%rbp)  2e:   31 c0                   xor    %eax,%eax  30:   48 8d 45 f7             lea    -0x9(%rbp),%rax  34:   49 89 c2                mov    %rax,%r10  37:   b8 00 00 00 00          mov    $0x0,%eax  3c:   e8 bf ff ff ff          callq  0 <fun.2287>  41:   b8 00 00 00 00          mov    $0x0,%eax  46:   e8 00 00 00 00          callq  4b <main+0x32>  4b:   b8 00 00 00 00          mov    $0x0,%eax  50:   48 8b 55 f8             mov    -0x8(%rbp),%rdx  54:   64 48 33 14 25 28 00    xor    %fs:0x28,%rdx  5b:   00 00   5d:   74 05                   je     64 <main+0x4b>  5f:   e8 00 00 00 00          callq  64 <main+0x4b>  64:   c9                      leaveq   65:   c3                      retq   0000000000000066 <fun>:  66:   55                      push   %rbp  67:   48 89 e5                mov    %rsp,%rbp  6a:   bf 00 00 00 00          mov    $0x0,%edi  6f:   e8 00 00 00 00          callq  74 <fun+0xe>  74:   90                      nop  75:   5d                      pop    %rbp  76:   c3                      retq   

结论

从反汇编和执行的结果看可以得到这样一个结论:GCC允许在函数中定义一个函数,而该函数的可见行和变量的一样,只能在当前代码块中可见。

备注

现在还不知道为何会允许这样,但这似乎和C语言标准不符。而这种用法在GRUB2的源代码中出现了,文件为grub-core/kern/i386/pc/init.c
下面为代码部分:

  auto int NESTED_FUNC_ATTR hook (grub_uint64_t, grub_uint64_t,                  grub_memory_type_t);  int NESTED_FUNC_ATTR hook (grub_uint64_t addr, grub_uint64_t size,                 grub_memory_type_t type)    {      /* Avoid the lower memory.  */      if (addr < 0x100000)    {      if (size <= 0x100000 - addr)        return 0;      size -= 0x100000 - addr;      addr = 0x100000;    }      /* Ignore >4GB.  */      if (addr <= 0xFFFFFFFF && type == GRUB_MEMORY_AVAILABLE)    {      grub_size_t len;      len = (grub_size_t) ((addr + size > 0xFFFFFFFF)         ? 0xFFFFFFFF - addr         : size);      add_mem_region (addr, len);    }      return 0;    }  grub_machine_mmap_iterate (hook);

更新

更深入的讨论见下面两篇文章
gcc官方文档
gcc官方文档中文解释

0 0
原创粉丝点击