Re: [fpc-devel] Capturing addresses
Jonas Maebe wrote: Hi, Does anyone know what the accepted/excepted behaviour is regarding the capture of addresses of var/out/const-by-address/constref parameters? For example: var g: longint; p: plongint; procedure test(var l: longint); begin p:=@l; end; begin test(g); end. After test() executes, p now contains the address of g (the '@' operator does not return the address of g's address on the stack; it returns the actual address of g). This means that g's address has been captured by test(). This can obviously lead to wrong/dangerous situations, e.g. if g was not a global variable, but a local variable of another procedure. That said, it is a legal expression. I would like to teach the compiler to be able to assume that addresses of variables are not captured merely because they are passed by reference. There will also be a switch to toggle this assumption, because fortunately it the behaviour is completely defined by the callee side (so if you know that a unit does this, compiling that unit appropriately is sufficient to ensure it will always work correctly). The question is: should the compiler by default assume that such addresses are not captured, or that they are captured? Does anyone know if a lot of code exists that does this? I've a lot of (interfacing) code where the address of a var is used, where the resulting pointer used locally. I don't think I've code which stores that pointer somewhere outside the procedure. Marc ___ fpc-devel maillist - fpc-devel@lists.freepascal.org https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel
Re: [fpc-devel] Capturing addresses
Il 10/11/2019 14:36, Jonas Maebe ha scritto: Hi, Does anyone know what the accepted/excepted behaviour is regarding the capture of addresses of var/out/const-by-address/constref parameters? For example: var g: longint; p: plongint; procedure test(var l: longint); begin p:=@l; end; begin test(g); end. The question is: should the compiler by default assume that such addresses are not captured, or that they are captured? Does anyone know if a lot of code exists that does this? To me p:=@l should be simply refused by the compiler as it happens in case of p:=l. Marco ___ fpc-devel maillist - fpc-devel@lists.freepascal.org https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel
Re: [fpc-devel] Capturing addresses
On 10/11/2019 15:05, Jonas Maebe wrote: On 10/11/2019 14:58, Martin Frb wrote: So I am trying to understand what the difference (in terms of safety) is? (except that the none "var param" is always unsafe, the "var param" is only sometimes unsafe)? If you are talking about the safety of accesses after the capturing routine has exited, then that is indeed the only difference. Ok then I am missing some (maybe internal?) detail. Not to important, just curiosity. ___ fpc-devel maillist - fpc-devel@lists.freepascal.org https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel
Re: [fpc-devel] Capturing addresses
On 10/11/2019 14:58, Martin Frb wrote: > So I am trying to understand what the difference (in terms of safety) > is? (except that the none "var param" is always unsafe, the "var param" > is only sometimes unsafe)? If you are talking about the safety of accesses after the capturing routine has exited, then that is indeed the only difference. > Also out of interest, what would change if you ... >> teach the compiler to be able to assume that addresses >> of variables are not captured merely because they are passed by >> reference It should allow the compiler to get rid of a lot of temporary function results (and copying those temporary results to their final destination), in particular for shortstring and set operations, and for overloaded operators that work with records. Jonas ___ fpc-devel maillist - fpc-devel@lists.freepascal.org https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel
Re: [fpc-devel] Capturing addresses
On 10/11/2019 14:36, Jonas Maebe wrote: For example: var g: longint; p: plongint; procedure test(var l: longint); begin p:=@l; end; begin test(g); end. After test() executes, p now contains the address of g (the '@' operator does not return the address of g's address on the stack; it returns the actual address of g). This means that g's address has been captured by test(). This can obviously lead to wrong/dangerous situations, e.g. if g was not a global variable, but a local variable of another procedure. That said, it is a legal expression. Your example shows the safe case (p is and will continue to be safe). In the unsafe case (g to be a local var), this is similar to none "var param" var p: plongint; procedure test(l: longint); begin p:=@l; end; p will be a dangling pointer, after "test" exited. The same as in your example, but with the case that "g" is local, p becomes dangling when "g" goes out of scope. So I am trying to understand what the difference (in terms of safety) is? (except that the none "var param" is always unsafe, the "var param" is only sometimes unsafe)? Also out of interest, what would change if you ... teach the compiler to be able to assume that addresses of variables are not captured merely because they are passed by reference ___ fpc-devel maillist - fpc-devel@lists.freepascal.org https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel
[fpc-devel] Capturing addresses
Hi, Does anyone know what the accepted/excepted behaviour is regarding the capture of addresses of var/out/const-by-address/constref parameters? For example: var g: longint; p: plongint; procedure test(var l: longint); begin p:=@l; end; begin test(g); end. After test() executes, p now contains the address of g (the '@' operator does not return the address of g's address on the stack; it returns the actual address of g). This means that g's address has been captured by test(). This can obviously lead to wrong/dangerous situations, e.g. if g was not a global variable, but a local variable of another procedure. That said, it is a legal expression. I would like to teach the compiler to be able to assume that addresses of variables are not captured merely because they are passed by reference. There will also be a switch to toggle this assumption, because fortunately it the behaviour is completely defined by the callee side (so if you know that a unit does this, compiling that unit appropriately is sufficient to ensure it will always work correctly). The question is: should the compiler by default assume that such addresses are not captured, or that they are captured? Does anyone know if a lot of code exists that does this? Jonas ___ fpc-devel maillist - fpc-devel@lists.freepascal.org https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel