Почему нет ошибки компилятора, когда оператор 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 Должен Знать О Неопределенном Поведении. Это очень поучительное чтение.