【问题标题】:c++ return from c'tor + default return values for err handlingc ++从c'tor返回+用于错误处理的默认返回值
【发布时间】:2015-08-10 19:00:39
【问题描述】:

我有几个宏,一个返回一个值,另一个返回 void 函数 case,基本上用它的参数和 (void)0 调用另一个。在使用 VS 和 GCC 进行编译时,在构造函数中调用它的情况下,我遇到了一些意想不到的编译问题。

我尝试运行以下命令,在 ubuntu 14.04 上使用 gcc b.cpp(gcc 版本 4.8.4)、clang c.bpp(clang 版本 3.4-1)和 win7 上的一些 VS2013 取消注释 5 个案例中的每一个,

#include <cstdio>

struct A {
    A() {
        return ((void)0);   // case 0 => gcc err,   clang ok,   msvc err
        //return (void)0;   // case 1 => gcc err,   clang ok,   msvc ok
        //return ();        // case 2 => gcc err,   clang err,  msvc err
        //return;           // case 3 => gcc ok,    clang ok,   msvc ok
        //;                 // case 4 => gcc ok,    clang ok,   msvc ok
    }
} a;

int main()
{
    printf("%p\n", &a);
}

我希望所有人都会产生类似的效果(好吧,我不确定情况 2),但我却遇到了一些奇怪的失败......

案例2:

$ gcc b.cpp
b.cpp: In constructor ‘A::A()’:
b.cpp:7:17: error: expected primary-expression before ‘)’ token
         return ();
                 ^
b.cpp:7:17: error: returning a value from a constructor
$ clang b.cpp
b.cpp:7:17: error: expected expression
        return ();
                ^
1 error generated.

案例一:

$ gcc b.cpp
b.cpp: In constructor ‘A::A()’:
b.cpp:6:22: error: returning a value from a constructor
         return (void)0;

案例 0:

$ gcc b.cpp
b.cpp: In constructor ‘A::A()’:
b.cpp:5:24: error: returning a value from a constructor
         return ((void)0);

这里的正确行为是什么?我该如何调整说几个宏,比如

#define MOO(a, b, retVal) \
    do                    \
        ...               \
        return (retVal);  \
   while(0)

#define FOO(a, b) MOO((a), (b), (void)0)

也为 c'tors 工作?是否有更 c++ 的方式来使用 decltype 返回 (void)0、-1、SOME_NONE 和其他默认值,以便在此类宏中中止错误处理?

(一个有点不相关的问题是,gcc 大约在代码中的什么位置决定我从 c'tor 返回一个值?)

【问题讨论】:

  • 为此使用宏的想法很愚蠢。重新考虑您的设计,改用模板化的内联函数!
  • 虽然这个想法很好,但对于我来说这并不是一个真正的选择,因为它需要能够从当前函数返回。
  • 除非你建议我手动操作堆栈?这也不是一个选择,TBH
  • 如果通过 void 函数调用返回可以在构造函数中工作会很有趣,因为从下面的答案中构造函数不应该使用带有值的return,而void 明确声明 没有价值.
  • 是的,这就是我的意思,规范说“从函数的末尾流出等同于没有值的返回;这会导致返回值的函数出现未定义的行为。”我认为这同样适用于c'tor。但另一方面,(void)0 也是无价值的,所以我认为它是等价的。

标签: c++ gcc language-lawyer return-type clang++


【解决方案1】:

根据 C++11 标准 12.1.8

构造函数主体中的返回语句不应指定返回值。

所以如果你从构造函数返回一个值应该是一个错误。

我相信 return (void)0; 作为构造函数中的返回不能使用的原因在 6.6.3.2 中有详细说明

既没有表达式也没有花括号初始化列表的 return 语句只能用于不返回值的函数,即返回类型为 cv void 的函数、构造函数 (12.1) 或析构函数 (12.4)。

由于(void)0 被认为是一个表达式,它不能在构造函数中使用。

【讨论】:

  • 我不想从 c'tor 返回一个值 - 我想使用现有的宏来执行 return 的等效操作。这个宏调用了一个现有的宏,它确实使用(void)0 执行return ...
  • @Guest86 但你是。 return ...; 将返回一个不允许的值。如果您只想退出构造函数,则可以像在 void 函数中一样使用return;
  • void moo() { return (void)0; }这样的普通函数中是合法的
  • @Guest86 构造函数不是普通函数,你不应该像对待它们一样对待它们。
  • @Guest86 德纳达!我想我们都从这个例子中学到了一些新东西 ;-) ...
猜你喜欢
  • 1970-01-01
  • 2016-04-30
  • 2018-04-02
  • 2010-09-26
  • 2019-03-15
  • 2018-05-07
  • 2018-09-23
  • 1970-01-01
  • 2021-02-09
相关资源
最近更新 更多