Мастера DELPHI, Delphi programming community Рейтинг@Mail.ru Титульная страница Поиск, карта сайта Написать письмо 
| Новости |
Новости сайта
Поиск |
Поиск по лучшим сайтам о Delphi
FAQ |
Огромная база часто задаваемых вопросов и, конечно же, ответы к ним ;)
Статьи |
Подборка статей на самые разные темы. Все о DELPHI
Книги |
Новинки книжного рынка
Новости VCL
Обзор свежих компонент со всего мира, по-русски!
|
| Форумы
Здесь вы можете задать свой вопрос и наверняка получите ответ
| ЧАТ |
Место для общения :)
Орешник
Коллекция курьезных вопросов из форумов
Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / rsdn.org

 
Чтобы не потерять эту дискуссию, сделайте закладку « предыдущая ветвь | форум | следующая ветвь »

Return value of function might be undefined, пользовательский тип


KSergey ©   (15.03.18 13:11

В Delphi есть замечательное предупреждение: W1035 Return value of function '%s' might be undefined

Если у функции стандартный возвращаемый тип
function GetXxx(...): Integer;
begin
end;

то указанное предупреждение работает отлично.

Однако если возвращается record

type TMyRec = ..... end;

function GetXxx(...): TMyRec;
begin
end;

то указанное предупреждение внезапно перестаёт выдаваться компилятором!!

Вопроса у меня два

1) WTF?!
2) Как бы сделать так, чтобы указанное предупреждение выдавалось не зависимо от возвращаемого типа?

Заранее спасибо.


ага ага ©   (15.03.18 13:45[1]

в первом случае скаляр и ругается на значение этого скаляра, которое может быть андефайнед

во втором случае не скаляр и что мы будем понимать под его значением, подразумевая возможную неопределенность?

резалт уже создан, память под него распределена.

ps кстати функция эта плохая.


ага ага ©   (15.03.18 13:56[2]

в рекорде сто строковых членов и триста ссылок на TObject
мной проинициализировано 99 строковых членов и 299 ссылок
299-я ссылка ведет в никуда. не в нил, а в недоступную память.

ты - компилятор.
в этом случае будешь предупреждать?
как и зачем?


Игорь Шевченко ©   (15.03.18 14:37[3]


> то указанное предупреждение внезапно перестаёт выдаваться
> компилятором!!


Ты посмотри, что вернется, а потом ругайся на компилятор.


Dimka Maslov ©   (16.03.18 11:52[4]

Формально такая запись означает
procedure GetXxx(out Result: TMyRec; .....)

Т.е. нет никакого возвращаемого результата, есть некий указатель, а что под ним лежит - ни разу не дело компилятора.


han_malign ©   (16.03.18 12:01[5]


> Ты посмотри, что вернется, а потом ругайся на компилятор.

- останется предыдущее значение, которое в большинстве случаев - стековый мусор.
В том числе веселый артефакт - для управляемых типов - при повторном вызове в той же области видимости:
function lime(s: string): string;
begin
   if( s <> '' )then
      Result:= s;
end;

const ss:array[0..1]of string = ('1', '');
var i;
begin
   i:= 0;
   if( lime('') = '' )then
      while( lime(ss[i]) <> '' )do inc(i);
end;


Поэтому полезно поддерживать портирование на FPC - там анализатор местами более параноидальный...

> 1) WTF?!

- в том числе FPC матерится на не инициализированный var параметр,  семантика которого здесь и имеет место быть.
procedure GetXxx(var : TMyRec);


han_malign ©   (16.03.18 12:14[6]

блин - тэг внутри выглядит оригинально...
...
function lime(s: string): string;
begin
   if( s <> '' )then
      Result:= s;
end;

const ss:array[0..1]of string = ('1', '');
var i;
begin
   i:= 0;
   if( lime('') = '' )then
      while( lime(ss[i]) <> '' )do inc(i);
end;


...

procedure GetXxx(var Result: TMyRec);


han_malign ©   (16.03.18 12:29[7]

блин(рекурсия): '&'+'gt' + ';'+'CODE'+'&'+'gt' + ';'  - тоже выглядит неплохо
особенно когда он внутри тэга '&'+'gt' + ';'+'DELPHI'+'&'+'gt' + ';'
...
function lime(s: string): string;
begin
   if( s <> '' )then
      Result:= s;
end;
 
const ss: array[0..1]of string = ('1', '');
var i: integer;
begin
   i:= 0;
   if( lime('') = '' )then
      while( lime(ss[i]) <> '' )do inc(i);
end;


...

procedure GetXxx(var Result: TMyRec);

(експеримент: а если так : (&+amp+;) &gt;> )


Игорь Шевченко ©   (16.03.18 12:43[8]

han_malign ©   (16.03.18 12:01) [5]


> - останется предыдущее значение


Ну так оно же не undefined, верно ? Оно вполне себе defined - то, что было перед вызовом


wert   (16.03.18 13:33[9]

GetXxx(...).SomeMember := 'bla bla bla';
ShowMessage(GetXxx(...).SomeMember);

формально все законно.

таких функций не должно быть на нашей планете


KSergey ©   (20.03.18 09:58[10]

> Игорь Шевченко ©   (16.03.18 12:43) [8]
> > - останется предыдущее значение
> Ну так оно же не undefined, верно ? Оно вполне себе defined
> - то, что было перед вызовом

Подождите, перед вызовом же ничего не было.


Игорь Шевченко ©   (20.03.18 10:15[11]

KSergey ©   (20.03.18 09:58) [10]


> Подождите, перед вызовом же ничего не было.


Я же предлагал посмотреть :)


KSergey ©   (23.03.18 13:30[12]

Игорь, я таки не понимаю про мусор на стеке, которым "проинициализировали".

Если написано

function НужнаяФункция(): Integer;
var
   i: integer;
begin
   Result:= i;
end;

то, вообще говоря, значение переменной i тоже вполне себе проинициализировано мусором. Но про это компилятор говорить не стесняется.
Или я что-то всё еще не понимаю?


KSergey ©   (23.03.18 13:30[13]

Про собственные типы данных и отсутствие указанного варнинга наверное тут такое соображение: если я проинициализировал 1 поле выходной структуры - это уже можно считать, что значение присвоено, или еще нет? и чтобы над этой дилеммой не размышлять - для пользоватльских типов такой варнинг и не работает...


Игорь Шевченко ©   (23.03.18 13:47[14]

KSergey ©   (23.03.18 13:30) [12]

В функцию, которая возвращает сложный тип, результат передается извне. Неявно. Компилятор внутри функции не может знать, проинициализирован он или нет.


wert   (23.03.18 13:50[15]

чудесное предположение.

особенно если вспомнить что ни одно из полей рекорда не имеет ни малейшего отношения к "Return value of function"


sniknik ©   (23.03.18 15:29[16]

надо писать так -

type TMyRec = ..... end;
PMyRec = ^TMyRec;

function GetXxx(...): PMyRec;
begin
end;

т.е. создавать переменные самому, не надеяться на "компилер маджик", или не создавать... тогда и сообщения появятся.

> Или я что-то всё еще не понимаю?
переменная и ее значение не одно и тоже.

p.s.
function GetXxx(...): string;
begin
end;
тоже не предупреждает, хотя тип не пользовательский (не надо зацикливаться на типе).


Игорь Шевченко ©   (23.03.18 16:05[17]


> надо писать так -
>
> type TMyRec = ..... end;
> PMyRec = ^TMyRec;


Это вредный совет


KSergey ©   (02.04.18 09:45[18]

> Игорь Шевченко ©   (23.03.18 13:47) [14]
> В функцию, которая возвращает сложный тип, результат передается
> извне. Неявно. Компилятор внутри функции не может знать,
>  проинициализирован он или нет.

Вот теперь до меня дошло, что было написано выше.
Спасибо.

Пользуясь случаем, передаю выдумщикам сего чуда отдельный пламенный привет. Уверен, они не замёрзнут.


KSergey ©   (02.04.18 09:46[19]

> sniknik ©   (23.03.18 15:29) [16]
> function GetXxx(...): PMyRec;
> begin
> end;

Возвращать из функции указатель на созданный внутри неё объект - ой.


Игорь Шевченко ©   (02.04.18 10:31[20]


> Возвращать из функции указатель на созданный внутри неё
> объект - ой.


Любой конструктор возвращает "созданный внутри функции объект" и как-то ничего, программы работают :)


sniknik ©   (02.04.18 11:49[21]

> Возвращать из функции указатель на созданный внутри неё объект - ой.
хочешь предупреждение? - возвращая явно тобой созданное. надеешься на "компилер маджик", когда за тебя дельфи создаст объект... забудь про предупреждение, т.к. система создать не забудет и вернет инициализированное, всегда.


KSergey ©   (03.04.18 09:22[22]

> sniknik ©   (02.04.18 11:49) [21]
> хочешь предупреждение? - возвращая явно тобой созданное.
>  надеешься на "компилер маджик",

Да кто ж знал, что в таком простом месте внезапно "компилер маджик"??


sniknik ©   (03.04.18 10:04[23]

а то, что не приходится выделять память под строки/объекты в других местах не удивляет? место неважно.


версия для печати

Написать ответ

Ваше имя (регистрация  E-mail 







Разрешается использование тегов форматирования текста:
<b>жирный</b> <i>наклонный</i> <u>подчеркнутый</u>,
а для выделения текста программ, используйте <code> ... </code>
и не забывайте закрывать теги! </b></i></u></code> :)


Наверх

  Рейтинг@Mail.ru     Титульная страница Поиск, карта сайта Написать письмо