int类型的函数未使用返回C++
Function of type int not using return C++
如果我有这样的函数:
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
,而我不使用返回。类似地,我可以写int answer = x
;并且它将返回CCD_ 7。我也可以这样写:
int addNumbers(int x, int y)
{
int answer = x;
answer = 1;
//return x + y;
}
并且它仍将返回4。
返回的究竟是什么?为什么?当我使用参数变量时,它只返回1以外的值,但它没有返回上一个示例中所示的变量答案,因为我将其更改为1,它仍然返回x (4)
的值。
§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++在-O2打印2
。
为什么?因为它推断出addNumbers(10, 20);
具有未定义的行为,这允许它假设第一个分支从未被采用,并且foo
总是true
,尽管显然不是这样。
您依赖的是"未定义的行为"。对于简单类型,返回值通常存储在寄存器中,该寄存器也可用于形成计算结果。但它也可能不被使用,你会得到一些任意的"随机"结果,作为"未定义的行为",你也可能会得到你的计算机可能执行的任何其他可能的操作,比如崩溃或执行一些你不想执行的代码。。。
您正在观察未定义的行为。没有充分的理由"为什么"这个程序会这样做,因为它不是一个格式良好的程序。它可以做任何事情,包括在运行时从磁盘中删除自己。启用编译器警告和错误(例如g++ -Wall -Wextra -Werror
),您将被自动阻止写入此类代码(应该如此)。
因此这是未定义的行为,反汇编二进制文件可以解释为什么会返回这样的值。
objdump -d example.bin
由于返回值与rax注册表相关联,因此如果编译器使用rax处理函数,则返回值是保留在rax中的值。
无论如何,您不应该这样做,因为在编写此类代码时,编译器优化和注册表的使用是未知的。
- 来自 std::list 的迭代器 .end() 按预期返回"0xcdcdcdcdcdcdcdcd"但 .begin()
- 什么时候在C++中返回常量引用是个好主意
- 你能重载对象变量名本身返回的内容吗
- 为什么 Serial.println(<char[]>);返回随机字符?
- C++映射:具有自定义类的运算符[]不起作用(总是返回0)
- 如何获取std::result_of函数的返回类型
- QueryWorkingSet总是返回false
- (C++)分析树以计算返回错误值的简单算术表达式
- 访问者访问变体并返回不同类型时出错
- 如何返回一个类的两个对象相加的结果
- OpenInventor从9.8升级到10.4.2后,GLSL纹理返回零
- lower_bound()返回最后一个元素
- "throw expression code" 1e7 >返回 d 是什么?投掷标准::overflow_error( "too big" ) : d;意味 着?
- 奇怪的(对我来说)返回声明 - 在谷歌上找不到任何关于它的信息
- 如何取消对nullptr的屏蔽,返回正确的对象
- 奇怪的结构&GCC&clang(void*返回类型)
- 架构决策:返回std::future还是提供回调
- 从python中调用C++函数并获取返回值
- 矩阵向量乘法(cublasDgemv)返回零
- 为什么模板类中的对象不能返回值