[英]C++ function returning string
#include <iostream>
using namespace std;
string test(string s)
{
string rv = "Hey Hello";
if(s=="")
return rv;
else
cout<<"Not returning"<<endl;
}
int main()
{
string ss = test("test");
cout<<ss<<endl;
}
上面的代码不应该返回任何值,并且可能会打印垃圾,但是即使在测试函数的末尾没有返回语句,它也返回“ Hey Hello ”。 你能告诉我为什么它会这样吗?
在没有任何return语句的情况下到达返回非void的函数的末尾是未定义的行为
如果它们处于活动状态,则应针对此类情况发出编译器警告
允许编译器假定未定义行为是不可实现的,因此编译器可能已删除了if语句,仅保留了不会导致未定义行为的分支
真诚的是,我正在对此代码进行编译感到惊讶! 您应该将警告视为错误。 警告很重要。
我的猜测是编译器作者认为:
每当编码器的分支没有返回语句时,这可能意味着她知道无法访问该分支(例如,在调用函数之前检查了参数的前提条件),因此可以删除该分支。
这可以解释为什么编译器以这种方式运行。 但是对您的问题的一个更正式的答案是:“这是未定义的行为,一切都会发生”。
尝试使用gcc进行编译时,输出取决于优化级别。
首先, test
函数会导致未定义的行为,因为它不会返回,因此实际上任何事情都可能发生。
但是,如果我稍作推测,该代码的行为可能是这样的,因为它不小心将曾经由rv
局部变量占用的内存块解释为返回值。 而那个物体恰好持有“ Hello World”。 因此,尽管该函数未正确返回,但可以将堆栈和堆上的内存解释为结果是本地变量。
但是,这只是一个猜测,根据C ++标准,这只是未定义的行为,这意味着您知道自己在做什么,并且永不执行该返回路径,或者代码只是错误。
正如泰克(Tyker)所提到的,此代码会导致未定义的行为,这意味着一切都会发生。
这很可能是由优化器引起的,该优化器假定每个执行分支都返回一些值,并基于此优化最终代码。 您应该尝试关闭优化,但是请注意,每个编译器都可以生成完全不同的结果。
看一下该函数的反汇编(clang 4.0,-O3)(我用char *代替了std :: string):
test: # @test
mov eax, .L.str.1
cmp rdi, rax
je .LBB0_2 // <<-- IF .L.str.1 == "", goto .LBB0_2
// CALL PRINTF
push rax
mov edi, .L.str.2
xor eax, eax
call printf
add rsp, 8
// END OF CALL PRINTF
.LBB0_2:
mov eax, .L.str // <<--- RETURN .L.str to the caller (optimization!)
ret
.L.str:
.asciz "Hey Hello"
.L.str.1:
.zero 1
无论是否生成语句,都将到达标签.LBB0_2,因此在每种情况下都将返回它。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.