Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2013.03.22;
Скачать: CL | DM;

Вниз

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;
Скачать: CL | DM;

Наверх




Память: 0.54 MB
Время: 0.05 c
15-1329633687
Sergey Masloff
2012-02-19 10:41
2013.03.22
Посоветуйте firewall для домашнего использования


15-1340952214
DevilDevil
2012-06-29 10:43
2013.03.22
Я В ШОКЕ. Стандарт округления в FPU


2-1342148174
delhpiCasual
2012-07-13 06:56
2013.03.22
Задваивается изображение формы


15-1339746265
ProgRAMmer Dimonych
2012-06-15 11:44
2013.03.22
Диаграмма сетевого взаимодействия


15-1334164870
ФордзБоярд
2012-04-11 21:21
2013.03.22
сложение цветов