繁体   English   中英

C ++函数返回字符串

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM