【问题标题】:Unclear about return value of a void function in C [closed]不清楚 C 中 void 函数的返回值 [关闭]
【发布时间】:2014-11-08 18:46:08
【问题描述】:

以下 C 程序有一个函数 test(),尽管没有 return 语句,但它返回:

  1. printf()格式的字符数
  2. 字符的 ASCII 值,如果单个字符以 printf() 的格式存在
  3. printf("") 的其中一个参数的值。

没有return 语句的函数如何返回值以及结果的可变性?


#include <stdio.h>
#include <stdlib.h>

int test(int, int);

int main(int argc, char **argv)
{
    printf("\n%d\n", argc);
    if (argc > 1)
    {
            printf("\n%d\n", test(atoi(*++argv), 2));
            printf("\n%d\n", test(2, atoi(*argv)));
    }

    return 0;
}

int test(int a, int b)
{
    printf("0");
}

【问题讨论】:

标签: c gcc


【解决方案1】:

从函数返回值的方式在不同的架构中是不同的。在大多数情况下,它是一些 CPU 寄存器的值。如果您没有专门使用return,则该寄存器的内容就是编译器“看到”为函数的返回值的内容。有时,它是最后一个调用函数的返回值,但有时它可能是其他东西。行为未定义。

【讨论】:

    【解决方案2】:

    你应该看看this slideshare第22页

    值被扔到寄存器中......这使得这种行为未定义。

    【讨论】:

      【解决方案3】:

      这种情况下的结果基于返回 test() 时堆栈顶部的内容。行为未定义。

      您应该在启用警告的情况下编译您的代码:

      gcc main.c -Wall

      另外,更改 argv 指针有点脏。取消引用 argv 会以清晰的方式直接传达您的意图:

      printf("\n%d\n", test(atoi(*++argv), 2));
      printf("\n%d\n", test(2, atoi(*argv)));
      

      应该是:

      printf("\n%d\n", test( atoi(argv[1]), 2) );
      printf("\n%d\n", test( 2, atoi(argv[1]) ) );
      

      【讨论】:

      • 谁说 OP 使用的任何 ABI 都会将返回值放在堆栈上?
      • 感谢@Luke Dupin,我尝试使用-Wall 参数,它返回:警告:控制到达非无效函数的结尾[-Wreturn-type]。另外,感谢您的编程技巧。由于所有答案中的所有原因,我猜输出将是未定义的。嗯,学到了一些新东西......
      • @Luke Dupin,我相信第 2 行中的 argv[2] 应该是 argv[1]。
      猜你喜欢
      • 1970-01-01
      • 2016-08-28
      • 2012-02-18
      • 1970-01-01
      • 2017-07-13
      • 2016-12-22
      • 2014-04-20
      • 2014-08-16
      • 1970-01-01
      相关资源
      最近更新 更多