int类型的函数不使用return C ++

时间:2014-09-06 08:42:06

标签: c++ return cout endl

如果我有这样的功能:

int addNumbers(int x, int y)
{
    return x + y;
}

如果我这样使用它:

cout << addNumbers(4, 5) << endl;

它将返回并打印9。使用上面相同的cout行,如果我在addNumbers中注释或删除回复,则会返回并打印1。如果我这样做:

int addNumbers(int x, int y)
{
    int answer = x + y;
    //return x + y;
}

它将自动返回并打印9,而不使用return。同样,我可以写int answer = x;它将返回4。我也可以这样写:

int addNumbers(int x, int y)
{
    int answer = x;
    answer = 1;
    //return x + y;
}

它仍将返回4.

究竟归还了什么?为什么?当我使用参数变量时,它只返回1以外的值,但它没有返回变量的答案,如上例所示,因为我将其更改为1并仍然返回x (4)的值。

4 个答案:

答案 0 :(得分:3)

§6.6.3[stmt.return] / p2:

  

离开函数末尾相当于return没有   值;这会导致值返回时出现未定义的行为   功能

main()是一个特殊例外。main()末尾的流量相当于return 0;

允许的UB包括:

  • 返回您“想要”返回的内容
  • 改为返回垃圾值
  • 崩溃
  • 将密码发送给黑客
  • 格式化硬盘
  • 让您的计算机爆炸并让您的腿脱落
  • 召唤鼻子恶魔
  • 回到过去并将程序修复到正确的位置
  • 制造黑洞
  • ......

但严重的是,UB可以通过各种方式表现出来。例如,给定此代码:

#include <iostream>
bool foo = false;
int addNumbers(int x, int y)
{
    int answer = x;
    answer = 1;
    //return x + y;
}

int main(){
  if(!foo) {
    addNumbers(10, 20);
    std::cout << 1 << std::endl;
  }
  else {
    std::cout << 2 << std::endl;
  }
}

clang ++ at -O2 prints 2

为什么呢?因为它推断出addNumbers(10, 20);具有未定义的行为,这允许它假设永远不会采用第一个分支,并且foo总是true,即使显然不是这种情况。

答案 1 :(得分:1)

您依赖于“未定义的行为”。对于简单类型,返回值通常存储在寄存器中,该寄存器也可用于形成计算结果。但是它也可能不被使用,并且你得到一些任意的“随机”结果,并且是“未定义的行为”,你也可能得到你的计算机可能执行的任何其他可能的操作 - 例如崩溃或执行你没有的一些代码想要执行......

答案 2 :(得分:0)

您正在观察未定义的行为。没有充分的理由“为什么”该计划会这样做,因为它不是一个结构良好的计划。它可以做任何事情,包括在运行时从磁盘中删除它自己。启用编译器警告和错误(例如g++ -Wall -Wextra -Werror),您将自动阻止编写此类代码(如您所愿)。

答案 3 :(得分:0)

因此它是未定义的行为,反汇编你的二进制文件可以解释为什么返回这些值。

objdump -d example.bin

由于返回值与rax注册表相关联,如果编译器使用rax处理函数,则返回的值是rax中保留的值。

无论如何,您不应该这样做,因为编写此类代码时,编译器优化和注册表的使用是未知的。