c++ return from c'tor + default return values for err handling

c++ return from c'tor + default return values for err handling

我有几个宏,一个 return 一个值,另一个 return 用于 void 函数的情况,基本上用它的参数和 (void)0 调用另一个。当同时使用 VS 和 GCC 编译它时,对于从构造函数中调用它的情况,我遇到了一些意想不到的编译问题。

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

#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.

案例 1:

$ 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++-ish 方法使用 decltype 到 return (void)0, -1, SOME_NONE 和其他默认值来处理此类宏中的错误处理中止?

(一个有点不相关的问题是,gcc 在代码的什么地方决定我 return 从 c'tor 获取一个值?)

根据 C++11 标准 12.1.8

A return statement in the body of a constructor shall not specify a return value.

因此,如果您 return 从构造函数中获取值,这应该是一个错误。

我相信 return (void)0; 作为构造函数中的 return 不能使用的原因在 6.6.3.2

中有详细说明

A return statement with neither an expression nor a braced-init-list can be used only in functions that do not return a value, that is, a function with the return type cv void, a constructor (12.1), or a destructor (12.4).

由于 (void)0 被视为表达式,因此不能在构造函数中使用。