Форум: "Прочее";
Текущий архив: 2013.03.22;
Скачать: [xml.tar.bz2];
ВнизDelphi 7: неверное предупреждение компилятора Найти похожие ветки
← →
Пит (2012-11-19 21:09) [0]Имеем Delphi 7, такой код:
function MyFunc: int64;
begin
Randomize;
try
if Random(10) < 0 then
raise Exception.Create("Какая-то хрень");
Result := Trunc(random(500));
finally
beep;
end;
end;
При компиляции данного кода имеем предупреждение:[Warning] Unit1.pas(36): Return value of function "MyFunc" might be undefined
Предупреждение получается ошибочное. Это известный глюк, с ним уже поборолись за столько лет?
Интересно как наиболее грамотно побороть это предупреждение?
← →
Dimka Maslov © (2012-11-19 21:12) [1]Глюк известный. Борется банально явным присваиванием в начале функции Result := 0;
← →
Медвежонок Пятачок © (2012-11-19 21:12) [2]function MyFunc: int64;
begin
Result := 0;
← →
Медвежонок Пятачок © (2012-11-19 21:13) [3]Предупреждение получается ошибочное.
с фига ли оно ошибочное?
исключение внутри рандомайза и привет.
← →
Dimka Maslov © (2012-11-19 21:16) [4]
> исключение внутри рандомайза и привет.
Результат функции тогда уже и не важен. Ошибка генерируется формально.
← →
Пит (2012-11-19 21:17) [5]
> Борется банально явным присваиванием в начале функции Result
> := 0;
ну это грубо. Тут ты теряешь контроль компилятора в том смысле, если реально где-то забудешь присвоить нужное возвращаемое значение.
Писать сразу в начале функции Result не подумав - это не умно, имхо
> с фига ли оно ошибочное?
> исключение внутри рандомайза и привет.
эхе хе, Пятачок, Пятачок ))
← →
Ega23 © (2012-11-19 21:17) [6]
Trunc(random(500))
Зачем Trunc?
← →
Dimka Maslov © (2012-11-19 21:21) [7]
> Пит (19.11.12 21:17) [5]
Никто не говорит, что такое присваивание необходимо в теле любой функции. Вот если мы хотим, чтобы компилятор заткнулся - самое то.
← →
Пит (2012-11-19 23:38) [8]
> Зачем Trunc?
незачем. Пример упрощался из реального кода, упростился не до конца )
> Вот если мы хотим, чтобы компилятор заткнулся - самое то.
да это понятно, но я тогда теряю возможность получить от компилятора вменяемое предупреждение, присваивая некий ничего не значащий результат...
Как я понимаю, компилятор ошибается в том контексте, что код обернут try..XXX и внутри кода генерируется исключение.
И если бы было обернуто в try..except, где в except не устанавливается код возврата - тогда верно. Но он это делает и в случае try..finally...
← →
TUser © (2012-11-20 00:17) [9]Голова у компилятора не резиновая - за программиста думать. Например, на
function aaa: integer;
var i: integer;
begin
i := 0;
if i = 1 then
result := 0
else
raise ...;
end;
тоже будет варнинг. Варнинг - это не замена мышления автора кода, а просто напоминание подумать. И хороший варнинг - не тот, который не вываливается на таких ошибках, а тот, который не пропускает те места, где реально надо просигналить - мол, ты, программист, кажись, фигню написал. Например,
function bbb: integer;
var i: integer;
begin
i := 0;
if i = 1 then
result := 0;
end;
← →
Пит (2012-11-20 01:13) [10]
> И хороший варнинг - не тот, который не вываливается на таких
> ошибках, а тот, который не пропускает те места, где реально
> надо просигналить - мол, ты, программист, кажись, фигню
> написал
верно, но я то в чем ошибся?
если я уберу блок try..finally - то предупреждение не будет писаться.
Но каким образом в данном случае обработка в секции finally влияет на результат? Ведь try..finally не глушит исключение, поэтому присваивать результат в finally бессмысленно, все равно исключение будет поднято дальше "вверх" и опираться на Result функции, которая отработала с исключением - глупо.
Вот в случае блока try..except предупреждение было бы логичным, ибо блок мог обработать исключение, но при этом не присвоение кода возврата как раз приводит к неопределенному результату функции.
Отсюда и ноги, наверное, растут. Предупреждение по сути должно показываться на try..except, но показывается на оба блока try..except/finally
← →
Пит (2012-11-20 01:13) [11]я на самом деле надеялся, что может данный глюк побороли в каком-то из обновлений D7
← →
Медвежонок Пятачок © (2012-11-20 05:00) [12]Результат функции тогда уже и не важен. Ошибка генерируется формально.
Ну генерируется-то не ошибка, а предупреждение.
О том, что иногда результат MyFunc может быть неопределен.
И это так.
← →
brother © (2012-11-20 05:06) [13]я не знаю, на сколько безопасна процедура randomize, но компилятору нуна верить, так что [1].
← →
icWasya © (2012-11-20 09:31) [14]А вот в соседнем форуме http://rsdn.ru/forum/cpp.applied/4963326.all ,
MSVC++ тоже куча предупреждений на ровном месте
← →
Дмитрий Белькевич (2012-11-20 10:39) [15]О чем вы, люди? Какой это глюк? При поднятии исключения результат функции будет не определен. Компилятор всё верно пишет.
← →
Компромисс © (2012-11-20 11:23) [16]
> О чем вы, люди? Какой это глюк? При поднятии исключения
> результат функции будет не определен. Компилятор всё верно
> пишет.
Неужели каждая функция должна быть в виде
try
...
except
on E:Exception do
begin
Result := ...;
raise
end
end
?
Глюк компилятора однозначно.
← →
RWolf © (2012-11-20 11:23) [17]Глюк, конечно. При поднятии исключения о результате функции речь уже не идёт, неважно, проинициализирован Result или нет. А варнинг призван указать именно на возможный возврат неинициализированного значения.
← →
Пит (2012-11-20 12:13) [18]Удалено модератором
← →
anatoly podgoretsky © (2012-11-20 12:40) [19]
> я на самом деле надеялся, что может данный глюк побороли
> в каком-то из обновлений D7
Нет никакого глюка, есть кривой код, на что ты надеешься после raise, что волшебно будет присвоение result?
← →
anatoly podgoretsky © (2012-11-20 12:40) [20]Удалено модератором
← →
Плохиш © (2012-11-20 12:45) [21]
> Нет никакого глюка, есть кривой код, на что ты надеешься
> после raise, что волшебно будет присвоение result?
В данном примере, после raise значение Result уже никого не волнует.
← →
anatoly podgoretsky © (2012-11-20 12:49) [22]И какой смысл делать бессмыленную проверку if Random(10) < 0
In Delphi code, Random returns a random number within the range 0 <= X < Range. If Range is not specified, the result is a real-type random number within the range
0 <= X < 1.
← →
Пит (2012-11-20 13:56) [23]
> Ну генерируется-то не ошибка, а предупреждение.
Медвежонок Пятачок, а почему тогда в примере:function MyFunc: integer;
begin
raise Exception.Create("Boom");
Result := 5;
end;
предупреждение не пишется?
И не будет писаться в других средах, например C# в подобной конструкции тоже ругаться не будет. И на мой взгляд совершенно правильно, что не будет.
А ты что думаешь? )
← →
Пит (2012-11-20 13:58) [24]
> есть кривой код, на что ты надеешься после raise, что волшебно
> будет присвоение result?
что и требовалось доказать. Можно хоть 20 лет писать на одном языке, но так и не понять элементарных вещей.
← →
Jeer © (2012-11-20 14:40) [25]
> но так и не понять элементарных вещей.
Согласен в отношении ТС.
Функция всегда должна возращать результат, иначе она должна называться процедурой.
← →
Пит (2012-11-20 15:15) [26]
> Функция всегда должна возращать результат, иначе она должна
> называться процедурой.
тут собственно можно считать как угодно. Но абсолютно точная мировая практика в том, что в случае возникновения исключений никто не анализирует результат функции.
Можно предположить такой код:try
MyID := MyFunc(...);
except on E: Exception do
begin
if MyID > 0 then WriteLog("Получен....")...
end;
end;
но любой нормальный программист скажет, что данный код бредовый и спроектирован неверно.
← →
Игорь Шевченко © (2012-11-20 17:30) [27]
> function MyFunc: int64;
> begin
> Randomize;
> try
> if Random(10) < 0 then
> raise Exception.Create("Какая-то хрень");
> Result := Trunc(random(500));
> finally
> beep;
> end;
> end;
Любой нормальный программист скажет, что этот код бредовый и спроектирован неверно.
← →
Пит (2012-11-20 17:33) [28]Удалено модератором
← →
Пит (2012-11-20 18:30) [29]Удалено модератором
Страницы: 1 вся ветка
Форум: "Прочее";
Текущий архив: 2013.03.22;
Скачать: [xml.tar.bz2];
Память: 0.52 MB
Время: 0.069 c