2010-08-01 71 views
50

我发现下面的代码被采用Visual C++ 2008和GCC 4.3编译器接受:返回无效的有效代码?

void foo() 
{ 

} 

void bar() 
{ 
    return foo(); 
} 

我有点惊讶的是它编译。这是一种语言功能还是它在编译器中的错误? C/C++标准对此有何评论?

回答

66

它的C++

C++语言特征(ISO 14882:2003)6.6.3/3

,类型为“CV空隙”的表达式的return语句可以在功能仅用于用cv void返回类型;该表达式在函数返回给调用者之前被评估。

C(ISO 9899:1999)6.8.6.4/1

带表达式的return语句不得出现在返回类型 是无效的功能。

+1

注意,许多编译器可以编译C和C++将提供C++规则作为非标准扩展在编译的C代码,但是这不应该依赖如果你想要便携。 – 2017-03-13 20:04:44

49

是的,它是有效的代码。当您有模板功能时,这是必要的,以便您可以使用统一代码。例如,

template<typename T, typename P> 
T f(int x, P y) 
{ 
    return g(x, y); 
} 

现在,g可能被重载以在第二个参数是某种特定类型时返回void。如果“返回无效”无效,则f的呼叫将会中断。

+1

'T'不能为空,因为参数不能为空。 – strager 2010-08-01 17:54:33

+0

谢谢,几分钟后我意识到自己已经给出了一个不好的例子。固定! – zvrba 2010-08-01 17:59:53

+3

此功能还会打开一个小陷阱:在void positive_action(int n){if(n <0)return;动作(N); [...]}',如果'action'返回void,那么在'return'后面忘记分号将不会给出错误或警告,但现在''action''会被调用,当''''是负数时,而不是正数时。 – 2014-04-18 07:13:20

5

这是有效的,可以是非常有用的,例如当你想在返回前做一些错误处理创建情况更清晰的代码:确实

void ErrRet(int code, char* msg) 
{ 
    // code logging/handling error 
} 
void f() 
{ 
    if (...) return ErrRet(5, "Error Message !"); 
    // code continue 
} 
1

有效。我用它经常输入验证宏:

#define ASSERT_AND_RETURN_IF_NULL(p,r) if (!p) { assert(p && "#p must not be null"); return r; } 

bool func1(void* p) { 
    ASSERT_AND_RETURN_IF_NULL(p, false); 
    ... 
} 

void func2(void* p) { 
    ASSERT_AND_RETURN_IF_NULL(p, void()); 
    ... 
}