Возвращает ли он действительный код?
Я узнал, что следующий код принимается компиляторами Visual С++ 2008 и GCC 4.3:
void foo()
{
}
void bar()
{
return foo();
}
Я немного удивлен, что он компилируется. Является ли это языковой функцией или это ошибка в компиляторах? Что говорят об этом стандарты C/С++?
Ответы
Ответ 1
Это языковая функция С++
С++ (ISO 14882: 2003) 6.6.3/3
Оператор return с выражением типа "cv void" может использоваться только в функциях с возвращаемым типом cv void; выражение оценивается непосредственно перед тем, как функция вернется к вызывающему.
C (ISO 9899: 1999) 6.8.6.4/1
Оператор return с выражением не должен появляться в функции, возвращаемый тип недействителен.
Ответ 2
Да, это действительный код. Это необходимо, когда у вас есть функции шаблона, чтобы вы могли использовать единый код. Например,
template<typename T, typename P>
T f(int x, P y)
{
return g(x, y);
}
Теперь g
может быть перегружен, чтобы вернуть void, когда второй аргумент является определенным типом. Если "return void" недействителен, вызов f
будет прерываться.
Ответ 3
Это справедливо и может быть весьма полезным, например, для создания более чистого кода в ситуациях, когда вы хотите выполнить некоторую обработку ошибок перед возвратом:
void ErrRet(int code, char* msg)
{
// code logging/handling error
}
void f()
{
if (...) return ErrRet(5, "Error Message !");
// code continue
}
Ответ 4
Действительно. Я часто использую его для макросов проверки ввода:
#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());
...
}