【问题标题】:C++ Function "Automatic" Return Value? [duplicate]C++ 函数“自动”返回值? [复制]
【发布时间】:2017-05-08 21:03:07
【问题描述】:

这是如何工作的?在编写这个函数时,我忘记包含return 声明:

char *getV(const char *var) {
    char *val = nullptr;
    forward_list<formField>::iterator idx;

    formField ffld;
    idx = _fields.begin();
    while (idx != _fields.end()) {
        ffld = *idx;
        if (strcmp(ffld.Name, var) == 0) {
            val = ffld.Val;
            break;
        }
        idx++;
    }
}

这里是formField:

struct formField {
    char    *Name   = nullptr;
    char    *Val    = nullptr;
};

这是我调用函数的方式:

int main () {
    form fdata;

    fdata.add("FirstName", "Alan");

    char *fval = fdata.getV("FirstName");
    if (fval != nullptr) cout << fval;
    else cout << "not found";
    cout << "\n";
}

直到后来,在测试了函数并编写了使用它的其他代码之后,我才注意到缺少的return。该函数应该返回*val...确实如此!怎么样?

【问题讨论】:

  • 未定义行为的永无止境的魔力。
  • 未定义的行为。 anything 是编译器允许的;你所期望的,没有,崩溃,格式化你的硬盘。您的代码格式不正确,没有任何意义。不,当您参与 UB 时,编译器不需要给您错误或警告。 你有责任“不要那样做”。
  • ...洗碗,给莫斯科的随机号码拨打淫秽电话...好吧,很有趣。谢谢。
  • @JesperJuhl 我明白了。这不是我故意做的,也不是打算按原样保留(除非结果涉及一些我不知道的明确行为)。
  • @TheTechel 这是一个有用的结构。谢谢。

标签: c++


【解决方案1】:

您平台的调用约定指定函数如何返回它想要返回给调用者的值(例如:保存在寄存器中)。由于寄存器存在,调用者代码只是获取它在那里找到的值,可能是垃圾,或者是偶然的实际好的值。无论哪种方式,您的程序都会调用未定义的行为,它不再受信任。

解决方案是打开编译器警告。例如,在 GCC 或 Clang 上:

g++ -Wall -Wextra -Werror

【讨论】:

    【解决方案2】:

    根据[stmt.return](强调我的):

    从构造函数、析构函数或具有 cv void 返回类型的函数的末尾流出等效于没有操作数的 return。 否则,从main 以外的函数末尾流出会导致未定义的行为。

    通常,您可以通过打开和读取编译器生成的警告来捕获这些类型的错误(例如,通过使用 GCC 或 Clang 的 -Wall -Wextra)。

    【讨论】:

    • 这不能回答问题。
    • @BoundaryImposition 是的。未定义的行为可以包括“返回值”。
    • OP 要求描述在这种情况下如何实现特定结果。就我个人而言,我通常把它留在“不要问这些问题”的建议下,但只是重复问题的前提并不能回答它。
    • 感谢你们俩。 “未定义的行为”是足够的答案,并且首先发布了 jotik,尽管 erenon 的答案在技术上更完整。我希望我能看到之前的问题,但它们没有出现在我的搜索中。
    • @Dayan 我想不是。如果对 erenon 很重要,我会更改并接受他/她的回答。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-06-29
    • 1970-01-01
    • 1970-01-01
    • 2011-03-09
    • 1970-01-01
    • 2020-12-03
    相关资源
    最近更新 更多