Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Прочее";
Текущий архив: 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.065 c
15-1340601785
Oleg1
2012-06-25 09:23
2013.03.22
Начинающим


15-1345031945
Рекрут
2012-08-15 15:59
2013.03.22
Как поменять маленькую иконку без VCL?


15-1340456276
stas
2012-06-23 16:57
2013.03.22
Свою кнопку в чужое приложение


15-1340113121
Eu
2012-06-19 17:38
2013.03.22
Как быстро вставить записи в oracle?


3-1277303472
VictorMBH
2010-06-23 18:31
2013.03.22
Какой инсталер нужен для инсталла BDE под 64 разрядной Windows 7





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский