Конференция "Начинающим" » Return value of function might be undefined, пользовательский тип
 
  • KSergey © (15.03.18 13:11) [0]
    В 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]
    а то, что не приходится выделять память под строки/объекты в других местах не удивляет? место неважно.
 
Конференция "Начинающим" » Return value of function might be undefined, пользовательский тип
Есть новые Нет новых   [118606   +35][b:0][p:0.002]