Почему нет ошибки компилятора, когда оператор return отсутствует?
в отличие от Java, в C/C++ и ниже разрешено:
int* foo ()
{
if(x)
return p;
// what if control reaches here
}
это часто вызывает сбои и проблемы с отладкой. Почему?--9-->стандартный не требует, чтобы окончательное возвращение для некурящихvoid
функции ? (Компиляторы генерируют ошибку для неправильного return
значение)
есть ли какой-либо флаг в gcc/msvc для обеспечения этого ? (что-то вроде -Wunused-result
)
7 ответов
это не разрешено (неопределенное поведение). Однако в данном случае стандарт не требует проведения диагностики.
стандарт не требует, чтобы последний оператор был return
из-за такого кода:
while (true) {
if (condition) return 0;
}
это всегда возвращает 0, но тупой компилятор не может видеть его. Обратите внимание, что стандарт не требует интеллектуальных компиляторов. А return
заявление после while
block будет пустой тратой, которую тупой компилятор не сможет оптимизировать. Стандарт не хочет требовать от программиста писать ненужный код только для того, чтобы удовлетворить тупой компилятор.
g++ -Wall достаточно умен, чтобы выдать диагностику на моей машине.
использовать -Wall
флаг gcc
.
warning: control reaches end of non-void function
редактировать: или более конкретно -Wreturn-type
.
мое предположение: потому, что иногда программист знает лучше, чем компилятор. В этом простом примере ясно, что что-то неправильно, но рассмотрим переключатель многих значений или много проверок в целом. Вы, как шифровальщик,знаю что определенные значения просто не будут переданы функции, но компилятор этого не делает и просто намекает вам, что может быть что-то не так.
#include <iostream>
int foo(){
if(false)
return 5;
}
int main(){
int i = foo();
std::cout << i;
}
отметим, что даже предупреждение уровень 1 на MSVC дает следующее внимание:
предупреждение C4715:' foo': не все пути управления возвращают значение
AFAIR Visual Studio 2008 предупреждает вас о "пути выполнения, который не имеет возвращаемого значения". Это разрешено в том смысле, что"C++ не остановит вас от стрельбы в ногу". Поэтому вы должны думать, а не компилятор.
ответ очевиден: потому что это не ошибка. Это только ошибка, если
x
false и если абонент использует возвращаемое значение, ни чего
всегда может быть определен компилятором, по крайней мере, в целом
случай.
в этом конкретном случае (возвращая указатель), это было бы не слишком
трудно требовать return
для всех путей; Java делает это. В
в общем, однако, в C++ не разумно требовать этого, так как в
C++, вы можете возвращать пользовательские типы для которых, возможно, невозможно
построить значение (нет конструктора по умолчанию, и т. д.) Итак, у нас есть
ситуация, когда программист не может предоставить return
в ветви, которую он или она знает, нельзя взять, и компилятор не может
определите, что ветвь не может быть взята.
большинство компиляторов будет предупреждать в таких случаях, когда он может определить поток. Все, кого я видел также предупреждают, в некоторых случаях, когда это явно однако упасть с конца невозможно. (Как g++, так и VC++ предупреждает о:
int
bar( char ch )
{
switch ( ch & 0xC0 ) {
case 0x00:
case 0x40:
return 0;
case 0x80:
return -1;
case 0xC0:
return 1;
}
}
по крайней мере с обычными вариантами. Хотя совершенно ясно, что это функция никогда не падает с конца.)
вы можете конвертировать предупреждение в ошибку, используя следующие параметры компилятора
-Wreturn-type -Werror=return-type
.
зацените ссылке
стандарт говорит об этом виде программирования, что он производит неопределенное поведение.
неопределенное поведение-это радость и жалость C/C++, но это также фундаментальная особенность языкового дизайна, которая позволяет для многих низкоуровневых оптимизаций, которые делают C своего рода "ассемблером высокого уровня" (это не так, на самом деле, но просто дать вам идею).
Итак, при перенаправлении на ответ Джона О коммутаторе для использования с GCC, чтобы знать "почему" стандарт не мешает этому, я бы указал на очень интересный анализ неопределенного поведения и всех его мистерий:Что Каждый Программист C Должен Знать О Неопределенном Поведении. Это очень поучительное чтение.