Vandrovnik 214 Posted January 30, 2022 15 minutes ago, dummzeuch said: And other calls to that procedure might actually require an input value: How should the compiler determine whether passing an uninitialized variable to procedure bla is a problem, without analyzing the procedure itself? OK, when we change it to this, so there is an unitialized variable: procedure bla(var _Value1: integer; _Value2: integer); begin if _Value2 > 0 then _Value1 := _Value2+1; end; procedure blub; var Value1: integer; begin bla(Value1, 3); writeln(Value1); end; What will be the value of Value1? I would prefer to get a warning in this case. Share this post Link to post
David Heffernan 2345 Posted January 30, 2022 2 hours ago, Uwe Raabe said: If a variable is given to a method as var or out parameter that should be sufficient to rate that variable as initialized inside that method. If that would always issue a warning, you will have to make a redundant initialization just to make the warning vanish. I strongly reject this request. In C# you can't pass an uninitialized variable to a ref param, but you can to an out param. Share this post Link to post
dummzeuch 1505 Posted January 30, 2022 59 minutes ago, Vandrovnik said: OK, when we change it to this, so there is an unitialized variable: procedure bla(var _Value1: integer; _Value2: integer); begin if _Value2 > 0 then _Value1 := _Value2+1; end; procedure blub; var Value1: integer; begin bla(Value1, 3); writeln(Value1); end; What will be the value of Value1? I would prefer to get a warning in this case. Easy: Value1 will be 4, since Value2 > 0 and therefore Value1 will be assigned Value2+1 = 3+1 = 4. So I guess your example has a bug. 😉 1 Share this post Link to post
dummzeuch 1505 Posted January 30, 2022 39 minutes ago, David Heffernan said: In C# you can't pass an uninitialized variable to a ref param, but you can to an out param. Yes, but that has always been the case, so there won't be any legacy code that passed an uninitialised variable to a ref parameter, and all of a sudden became invalid code. Delphi introduced the out parameter declaration "recently" (Delphi 5?), so there is legacy code that uses var rather than out. OK I change my vote to: This should emit a hint or a warning, because nowadays it's bad design and should be fixed ASAP. 1 Share this post Link to post
David Heffernan 2345 Posted January 30, 2022 4 minutes ago, dummzeuch said: Yes, but that has always been the case, so there won't be any legacy code that passed an uninitialised variable to a ref parameter, and all of a sudden became invalid code. Delphi introduced the out parameter declaration "recently" (Delphi 5?), so there is legacy code that uses var rather than out. I understand all of that, hence my first post. I explained why Delphi behaves the way it does, because var is both in/out and out. Share this post Link to post
Dalija Prasnikar 1396 Posted January 30, 2022 12 minutes ago, dummzeuch said: OK I change my vote to: This should emit a hint or a warning, because nowadays it's bad design and should be fixed ASAP. But, Delphi out parameters have some unpleasantries and many developers choose to use var instead. https://delphisorcery.blogspot.com/2021/04/out-parameters-are-just-bad-var.html 1 Share this post Link to post
Vandrovnik 214 Posted January 30, 2022 37 minutes ago, dummzeuch said: Easy: Value1 will be 4, since Value2 > 0 and therefore Value1 will be assigned Value2+1 = 3+1 = 4. So I guess your example has a bug. 😉 Ups, yes, it has a bug 🙂 I was reading it as _Value1 := _Value1+1; Share this post Link to post
Attila Kovacs 629 Posted January 30, 2022 2 hours ago, David Heffernan said: In C# you can't pass an uninitialized variable to a ref param, but you can to an out param. Why is it relevant how c# works? It's completely different. won't compile: bool a(out int i) { if (1 != 2) return false; i = 43; return true; } Share this post Link to post
David Heffernan 2345 Posted January 30, 2022 11 minutes ago, Attila Kovacs said: It's completely different. Because it has been designed correctly with ref, out and by value arguments handling the three different parameter semantics. C# is an example of how delphi should be, and the entire issue with this missing warning is because delphi is so badly designed in this area. 4 Share this post Link to post
Attila Kovacs 629 Posted January 30, 2022 1 minute ago, David Heffernan said: Because it has been designed correctly with ref, out and by value arguments handling the three different parameter semantics. C# is an example of how delphi should be, and the entire issue with this missing warning is because delphi is so badly designed in this area. but c# does not only giving hints, it is enforcing a lot of things. or is it possible to turn them off? Share this post Link to post
David Heffernan 2345 Posted January 30, 2022 4 minutes ago, Attila Kovacs said: but c# does not only giving hints, it is enforcing a lot of things. or is it possible to turn them off? A variable has to be initialized before being passed to a ref param Share this post Link to post
Attila Kovacs 629 Posted January 30, 2022 1 minute ago, David Heffernan said: A variable has to be initialized before being passed to a ref param A variable has to be initialized before being passed to a ref param, yes you have to decorate with "ref" or "out" -or whatever- the parameters at call: myproc(ref param1, out param2); <- this is the call, not the definition! you _have_ to set an "out" parameter before using it or before returning from the routine, even if you won't use that value (see my example) who knows what else... And I'm afraid this is because you can't just show hints for coding guidance as they will first disappear when you do what the compiler wants you to do. So it would be basically an error, like in c#. Am I right? Do we need that? Share this post Link to post
Uwe Raabe 2057 Posted January 30, 2022 There are probably plenty of methods, built-in or from 3d party libraries, that offer only var parameters where out would be the better choice, but we are not able to change the signature. Share this post Link to post
David Heffernan 2345 Posted January 30, 2022 44 minutes ago, Uwe Raabe said: There are probably plenty of methods, built-in or from 3d party libraries, that offer only var parameters where out would be the better choice, but we are not able to change the signature. The thing is, for value types, there is actually no practical difference between var and out in Delphi which is the problem. In practice out and var behave identically. So what's the point of out? I appreciate that legacy makes it hard to change. It was just a screw up by the designers that leads to oddities like the absent warning in this question. Share this post Link to post
Uwe Raabe 2057 Posted January 30, 2022 58 minutes ago, David Heffernan said: So what's the point of out? One could argue that an out parameter counts as initialized while a var does not. Due to the history of var/out that doesn't work in a consistent manner. As @Dalija Prasnikar said, out has its merits, too. Share this post Link to post
David Heffernan 2345 Posted January 30, 2022 11 minutes ago, Uwe Raabe said: One could argue that an out parameter counts as initialized while a var does not. Due to the history of var/out that doesn't work in a consistent manner. As @Dalija Prasnikar said, out has its merits, too. Without the compiler enforcing it, it's next to pointless 1 Share this post Link to post
Fr0sT.Brutal 900 Posted January 31, 2022 On 1/29/2022 at 10:20 PM, aehimself said: What can be the explanation? I guess the reason is the way you call the function. Likely the code before function call zeroed the corresponding stack area on x32 but didn't on x64 Share this post Link to post
Kryvich 165 Posted January 31, 2022 (edited) 13 hours ago, Dalija Prasnikar said: But, Delphi out parameters have some unpleasantries and many developers choose to use var instead. https://delphisorcery.blogspot.com/2021/04/out-parameters-are-just-bad-var.html Good article. The main point against using the out parameter in Delphi is sub-optimal generated code, due to the need to maintain compatibility with C++ Builder. But how often is Delphi code used in C++? Maybe a better solution would be to add additional checks and parameter initializations to the calling C++ code? Edited January 31, 2022 by Kryvich Share this post Link to post
Kryvich 165 Posted January 31, 2022 (edited) 18 hours ago, Attila Kovacs said: It's not the compilers job to do code analysis for you? Checking the initialization of var parameters before use is a basic thing that does not require deep analysis. In fact, it has already implemented for parameters passed by value. procedure Test; procedure DoStuff({var} a: Integer); begin if a = 0 then a := 1; end; var a: Integer; begin DoStuff(a); // W1036 Variable 'a' might not have been initialized Writeln(a); end; Edited January 31, 2022 by Kryvich Share this post Link to post
David Heffernan 2345 Posted January 31, 2022 40 minutes ago, Kryvich said: In fact, it has already implemented for parameters passed by value. Indeed. And it is simply the fact that var serves as both in/out and out that explains why there is no such warning for var parameters. Since we have out then a very simple thing for the designers to do would be to enable this very warning for var parameters too. If you encountered it on a var that was masquerading as a pure out parameter, you could simply change the parameter definition to be out. 2 Share this post Link to post
Attila Kovacs 629 Posted January 31, 2022 1 minute ago, David Heffernan said: If you encountered it on a var that was masquerading as a pure out parameter, you could simply change the parameter definition to be out. that won't help much as out parameter also taking inputs without any warnings, which is more screwed as the original problem Share this post Link to post
Uwe Raabe 2057 Posted January 31, 2022 24 minutes ago, David Heffernan said: If you encountered it on a var that was masquerading as a pure out parameter, you could simply change the parameter definition to be out. As I said, this may not always be possible: 12 hours ago, Uwe Raabe said: There are probably plenty of methods, built-in or from 3d party libraries, that offer only var parameters where out would be the better choice, but we are not able to change the signature. 1 Share this post Link to post
Kryvich 165 Posted January 31, 2022 (edited) 26 minutes ago, Attila Kovacs said: that won't help much as out parameter also taking inputs without any warnings, which is more screwed as the original problem The compiler should generate absolutely the same code for var and out parameters, both for the calling and for the called subroutines. The only difference will be in the warnings it issues: Warning var parameter out parameter Where to show 1. W1036 Variable might not have been initialized yes no Calling routine 2. The parameter must be initialized before use no yes Called routine 3. Return value of parameter might be undefined no yes Called routine Warnings 2. and 3. should work in the same way as for the Return value of a function (W1035 Return value of function might be undefined). That is, all the necessary checks (W1035, W1036) are already in the compiler, Embarcadero only has to apply them to the parameters where necessary. Edited January 31, 2022 by Kryvich Share this post Link to post
Attila Kovacs 629 Posted January 31, 2022 as I mentioned before, to avoid the hints you have to act so you could make it an error instead of a hint or are you the guy who having 2 kilometer of hints after a build? Share this post Link to post
Dalija Prasnikar 1396 Posted January 31, 2022 1 hour ago, Kryvich said: Good article. The main point against using the out parameter in Delphi is sub-optimal generated code, due to the need to maintain compatibility with C++ Builder. But how often is Delphi code used in C++? Maybe a better solution would be to add additional checks and parameter initializations to the calling C++ code? Easier said than done. Share this post Link to post