[fpc-devel] Variable can not be initialized by named constant
Since issue http://bugs.freepascal.org/view.php?id=13256 was marked resolved, I can not add comments, so I'd like to discuss it here. Original report claimed that code const c: SomeType = value; var y: t = c; begin end. Works for primitive types, but not the complex ones. This was an error on my part, as pointed out on the issue tracker: It also does not work with other types for me, unlike what's stated in the Additional Information section It also does not work in Delphi, so this is certainly a design decision. However, I think this decision is suboptimal. This is a typical use case: const EMPTY_RECT: TRect = (Left: 0; Right: 0; Top: 0; Bottom: 0); ... var myRect: TRect = EMPTY_RECT; I think this is quite reasonable to expect this to work. The writeability of constants is IMNSHO just an ugly leftover from Delphi history, and should be disabled in _both_ delphi and objfpc modes: {$IFDEF FPC}{$MODE DELPHI}{$ENDIF} const x: integer = 1; begin x := 3; end. Is rejected by Delphi, but compiled by FPC, which is a compatibility bug in itself. So how about re-submitting the issue as a feature request? -- Alexander S. Klenin ___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-devel
Re: [fpc-devel] Variable can not be initialized by named constant
On 01 Mar 2009, at 15:29, Alexander Klenin wrote: I think this is quite reasonable to expect this to work. The writeability of constants is IMNSHO just an ugly leftover from Delphi history, and should be disabled in _both_ delphi and objfpc modes: {$IFDEF FPC}{$MODE DELPHI}{$ENDIF} const x: integer = 1; begin x := 3; end. Is rejected by Delphi, but compiled by FPC, which is a compatibility bug in itself. This depends on a mode switch. Use {$j-} to turn off the ability to write to typed constants. Maybe it's off by default in your version of Delphi. So how about re-submitting the issue as a feature request? You can try, but I'm afraid it'll stay open for quite a long time if no one also submits a patch. Jonas ___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-devel
Re: [fpc-devel] Variable can not be initialized by named constant
On Mon, Mar 2, 2009 at 00:47, Jonas Maebe jonas.ma...@elis.ugent.be wrote: Is rejected by Delphi, but compiled by FPC, which is a compatibility bug in itself. This depends on a mode switch. Use {$j-} to turn off the ability to write to typed constants. Maybe it's off by default in your version of Delphi. I know. I argued that it should be off by default in FPC too -- in Delphi mode because of compatibility, in FPC mode because it is sane. So how about re-submitting the issue as a feature request? You can try, but I'm afraid it'll stay open for quite a long time if no one also submits a patch. Of course, this is open source ;-) Main goal of the present discussion for me is to get sure the request will not be closed as won't fix. -- Alexander S. Klenin ___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-devel
Re: [fpc-devel] Variable can not be initialized by named constant
On 01 Mar 2009, at 15:58, Alexander Klenin wrote: On Mon, Mar 2, 2009 at 00:47, Jonas Maebe jonas.ma...@elis.ugent.be wrote: This depends on a mode switch. Use {$j-} to turn off the ability to write to typed constants. Maybe it's off by default in your version of Delphi. I know. I argued that it should be off by default in FPC too -- in Delphi mode because of compatibility, It depends on which Delphi you want to be compatible with. In general, FPC aims for compatibility with Delphi 7, and at least in Kylix 3 (~ Delphi 6.5) the default is {$j+} in FPC mode because it is sane. And would break backwards compatibility. You can try, but I'm afraid it'll stay open for quite a long time if no one also submits a patch. Of course, this is open source ;-) Main goal of the present discussion for me is to get sure the request will not be closed as won't fix. I don't think there is a way to be sure of that, but it seems unlikely to me that it will be closed immediately if you phrase it purely as a feature request. Jonas ___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-devel
Re: [fpc-devel] Variable can not be initialized by named constant
Op Mon, 2 Mar 2009, schreef Alexander Klenin: Since issue http://bugs.freepascal.org/view.php?id=13256 was marked resolved, I think this is quite reasonable to expect this to work. The writeability of constants is IMNSHO just an ugly leftover from Delphi history, and should be disabled in _both_ delphi and objfpc modes: Making typed constants writeable has been a disputed feature of the Borland dialect, I agree with that, but fact of the matter is they are writeable and thus cannot form a constant expression. The fact that there exists a $J directive does not change this. There are some estethic arguments against this: allowing them into initalization results in a break of the separation between declarations and code Pascal has: The declaration suddenly gets an assignment statement built-in. I forsee also practical problems: Procedure initialization code would become much more complex. Rather than storing a fixed value in a variable one would need to take care of dynamic types, like ansistring management. Daniël___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-devel
Re: [fpc-devel] Variable can not be initialized by named constant
On Mon, Mar 2, 2009 at 03:16, Daniël Mantione daniel.manti...@freepascal.org wrote: Making typed constants writeable has been a disputed feature of the Borland dialect, I agree with that, but fact of the matter is they are writeable and thus cannot form a constant expression. The fact that there exists a $J directive does not change this. Well, I'd say a better way that, in Delphi, there exists an unfortunately designed obscure option to make them writeable. I think that that option default is even more unfortunate -- Pascal language was always distinguished for its clarity and clean design, and 'writeable constants' is neither clear nor clean, IMO. There are some estethic arguments against this: allowing them into initalization results in a break of the separation between declarations and code Pascal has: The declaration suddenly gets an assignment statement built-in. I forsee also practical problems: Procedure initialization code would become much more complex. Rather than storing a fixed value in a variable one would need to take care of dynamic types, like ansistring management. First, allowing to write to a constant is much more aesthetically unpleasant to me. Actually, Free Pascal is the almost the only language I know (besides assembler and FORTRAN IV) allowing such break-of-contract by default, without the need of any casts or pointers. Second, I do NOT suggest to convert declaration into an assignment. As you correctly noted, it is debatable whether such a feature is good or bad for the language. Although I personally think that benefits outweigh the costs, this is totally separate topic. What I suggest is to: 1) Disallow changing of constants, making them worth their name 2) Allow using of typed constants at the same places as untyped ones, including initializer expressions. This should not affect code generation at all, just parsing an constant folding. -- Alexander S. Klenin ___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-devel
Re: [fpc-devel] Variable can not be initialized by named constant
Op Mon, 2 Mar 2009, schreef Alexander Klenin: On Mon, Mar 2, 2009 at 03:16, Daniël Mantione daniel.manti...@freepascal.org wrote: Making typed constants writeable has been a disputed feature of the Borland dialect, I agree with that, but fact of the matter is they are writeable and thus cannot form a constant expression. The fact that there exists a $J directive does not change this. Well, I'd say a better way that, in Delphi, there exists an unfortunately designed obscure option to make them writeable. I think that that option default is even more unfortunate -- Pascal language was always distinguished for its clarity and clean design, and 'writeable constants' is neither clear nor clean, IMO. This is a debate that has been held quite a few times :) If you look at typed consts from the point of view what a mathematical constant is, yes, it's completely absurd that you can write to them. But... you need to look at typed consts what they do, and not how they are named. If you look at the language feature typed consts from you will see that they are not mathematical constants that exists only at compile time. If you want a real constant that just has a type you can do something like const x=longint(1). In contrast with constants, typed consts describes actual data that will appear in memory. The compiler cannot prevent you writing to data in memory, since at runtime, the coder is the boss. All you need is to cast them into a pointer. Works flawlessly, regardless of the $J state. From this point of view of the function typed consts form, allowing writes to them isn't that illogical. First, allowing to write to a constant is much more aesthetically unpleasant to me. Actually, Free Pascal is the almost the only language I know (besides assembler and FORTRAN IV) allowing such break-of-contract by default, without the need of any casts or pointers. Second, I do NOT suggest to convert declaration into an assignment. As you correctly noted, it is debatable whether such a feature is good or bad for the language. Although I personally think that benefits outweigh the costs, this is totally separate topic. What I suggest is to: 1) Disallow changing of constants, making them worth their name 2) Allow using of typed constants at the same places as untyped ones, including initializer expressions. This should not affect code generation at all, just parsing an constant folding. Remember again that: const x:longint=1;{Defines a location in memory large enough to hold an integer, which contains value 1.} y=longint(1); {Defines a compile-time symbol that is equavalent to writing longint(1) somewhere in the code.} ... do completely different things inside the compiler. It will affect code generation, since typed consts are stored in memory. There exists no constant folding for typed consts, because they need to be layed out in memory exactly as the programmer describes, the compiler cannot mess with that unlike with real compile-time constants. Basically code has to be generated that reads the typed consts from their fixed position in memory and copied into the variable. Of course disallowing writing to typed consts is problematic because of people making use of this functionality. After all, typed consts existed long before initialized variables were invented and I'm sure people are still using them. Daniël___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-devel
Re: [fpc-devel] Variable can not be initialized by named constant
On Mon, Mar 2, 2009 at 07:34, Daniël Mantione daniel.manti...@freepascal.org wrote: This is a debate that has been held quite a few times :) If you look at typed consts from the point of view what a mathematical constant is, yes, it's completely absurd that you can write to them. From _mathematical_ point of view assignment to a variable is just as nonsensical as assignment to a constant, but this is ok since programming language is not a math notation. To write to a constant is absurd from _programmer's_ point of view, which is much worse in this case. But... you need to look at typed consts what they do, and not how they are named. [skipped explanation] I know this, but this is backwards reasoning. Implementation details should not affect semantics. The compiler cannot prevent you writing to data in memory, since at runtime, the coder is the boss. All you need is to cast them into a pointer. It can, it just currently chooses not to. This C++ code: const int x = 1; int main() { *(int*)x = 2; return 0; } compiles, but causes access violation at run-time. Works flawlessly, regardless of the $J state. From this point of view of the function typed consts form, allowing writes to them isn't that illogical. By using pointers, you can access private fields of an object, change local variables of calling procedure, ignore variable types and array boundaries. Does this mean that Pascal should abolish variable scopes, type safety, range checking? No, this would turn it into an assembler language with Pascal-like syntax. I believe const-correctness (to borrow a term from C++) is as important as type safety, and should not be abolished as well. const x:longint=1; {Defines a location in memory large enough to hold an integer, which contains value 1.} y=longint(1); {Defines a compile-time symbol that is equavalent to writing longint(1) somewhere in the code.} ... do completely different things inside the compiler. Yes, they do now, this is what I think is wrong. What I am trying to say is that they should do (almost) the same thing. It will affect code generation, since typed consts are stored in memory. This is the only difference that should remain -- to allow passing of (read-only) typed constant and a const parameter. There exists no constant folding for typed consts, because they need to be layed out in memory exactly as the programmer describes, the compiler cannot mess with that unlike with real compile-time constants. I am not sure what you mean here. How does compiler mess with constants? Basically code has to be generated that reads the typed consts from their fixed position in memory and copied into the variable. Why? What prevents the compiler from inlining constant value just like it does with untyped constants? Of course disallowing writing to typed consts is problematic because of people making use of this functionality. After all, typed consts existed long before initialized variables were invented and I'm sure people are still using them. Borland did this long ago, in Delphi 6, and I do not recall large problems with that change. Of course in Turbo Pascal mode they should stay on by default. -- Alexander S. Klenin ___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-devel