【问题标题】:Whether in C, a called function automatically returns value returned by its called function if not written explicitly?在 C 语言中,如果没有显式编写,被调用函数是否会自动返回其被调用函数返回的值?
【发布时间】:2014-05-10 17:58:07
【问题描述】:

我有如下代码。并且函数 slogan 总是返回 printf 返回的值,即正在打印的字符数。是否按照 C 编译器定义?完全返回机制的隐含概念是什么?

#include <stdio.h>

int main()
{
  int slogan( ) ;
  int c = 5 ;
  c = slogan( ) ;
  printf ( "\n%d", c ) ;
}

int slogan( )
{
  printf ( "\nOnly He men use C!" ) ;
}

【问题讨论】:

    标签: c function return


    【解决方案1】:

    这是undefined behavior 使用返回值时你丢弃一个值返回函数的结尾,你不能依赖这个行为。

    这在草案 C99 标准部分 6.9.1 函数定义12 段中有所涉及:

    如果到达终止函数的},并且函数调用的值被 调用者,行为未定义。

    与 C11 标准草案中的部分和段落相同。

    在您的情况下,它只能靠运气起作用,可能返回值在您返回时不会被覆盖的寄存器中返回。对于System V calling convention 将在eax/rax 中返回一个足够小的参数,如果我们查看带有-fverbose-asm 标志的稍微修改过的测试程序live on Coliru using gcc

    #include <stdio.h>
    
    int main()
    {
      int slogan( ) ;
      int c = 5, d ;
      c = slogan( ) ;
      d = printf ( "\n%d", c ) ;
      printf ( "\n%d", d ) ;
    }
    
    int slogan( )
    {
      printf ( "\nOnly He men use C!" ) ;
    }
    

    我们可以从程序集中看到cdeax获取它们的值:

    movl    %eax, -4(%rbp)  # tmp61, c
    movl    -4(%rbp), %eax  # c, tmp62
    movl    %eax, %esi      # tmp62,
    movl    $.LC0, %edi
    movl    $0, %eax
    call    printf  
    movl    %eax, -8(%rbp)  # tmp63, d
    movl    -8(%rbp), %eax  # d, tmp64
    movl    %eax, %esi      # tmp64,
    movl    $.LC0, %edi 
    movl    $0, %eax
    call    printf
    

    【讨论】:

    • “返回值在一个寄存器中返回,当你返回时不会被覆盖”这似乎是答案,即使我再打一个电话! main->A->B->C... 与 A 并没有什么可以返回。
    猜你喜欢
    • 2023-01-02
    • 1970-01-01
    • 2015-06-26
    • 2016-03-26
    • 2013-10-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-03-30
    相关资源
    最近更新 更多