[fpc-pascal] Re: classes initialization
What about old borland objects (heap and stack initialization) process? I am guessing they are more like records... or do heap objects act like classes in that they are filled with zeros? p.s. I think the inconsistent behavior between local scope records and global scope records is kind of a flaw/danger in modern pascal.. as the bugs may not be caught until someone builds a program with local scope var.. and for eg. many demonstrations are built in simple global console programs as test cases. Nowadays I always (try to) build things inside a procedure in a test case to ensure local scope is being used. But as humans make mistakes, again I think this part of modern pascal can be improved and we should push to the language less dangerous by default. ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] Re: classes initialization
On 25 Mar 2008, at 13:40, L wrote: What about old borland objects (heap and stack initialization) process? I am guessing they are more like records... They are exactly like records. or do heap objects act like classes in that they are filled with zeros? Unlike classes, objects have no hidden dereferencing or whatever and follow exactly the same semantics as other types regardless of whether they are on the stack or on the heap. p.s. I think the inconsistent behavior between local scope records and global scope records is kind of a flaw/danger in modern pascal.. as the bugs may not be caught until someone builds a program with local scope var.. Using uninitialised variables is virtually always bad, regardless of the scope. And the fact that global variables are zeroed at the program start is afaik not defined by the Pascal standard. It's just a side effect of the way most operating systems work. Jonas ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-pascal
[fpc-pascal] Re: classes initialization
I wrote: What about old borland objects (heap and stack initialization) process? program test1; type trec = record i: integer; end; tclass = class i: integer; end; tobj = object i: integer; end; pobj = ^Tobj; procedure show; var rec: trec; c: tclass; o: tobj; po: pobj; begin writeln('Record local:', rec.i); c:= tclass.create; new(po); writeln('Class local:', c.i); writeln('Stack Object local:', o.i); writeln('Heap Object local:', po^.i); c.free; c:= nil; dispose(po); end; var rec: trec; c: tclass; o: tobj; po: pobj; begin show; writeln('Record global:', rec.i); c:= tclass.create; new(po); writeln('Class global:', c.i); writeln('Stack Object global:', o.i); writeln('Heap Object global:', po^.i); c.free; c:= nil; dispose(po); readln; end. Not a fool proof test since random values have a chance of being zero, but it basically shows: 1. global old heap object NOT zeroed 2. local old heap object NOT zeroed 3. local class zeroed 4. global class zeroed 5. global old stack object zeroed 6. local old stack object NOT zeroed 7. global stack record zeroed 8. local stack record NOT zeroed. I didn't bother with heap records but we can see what will happen -- L505 ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] Re: classes initialization
p.s. I think the inconsistent behavior between local scope records and global scope records is kind of a flaw/danger in modern pascal.. as the bugs may not be caught until someone builds a program with local scope var.. Using uninitialised variables is virtually always bad, regardless of the scope. And the fact that global variables are zeroed at the program start is afaik not defined by the Pascal standard. It's just a side effect of the way most operating systems work. Affirmative. Pascal does not define any variable initialization itself - one should always init all Pascal vars of any type. Doing so is an excellent coding habit also portable to any other language/OS - protects against low-level implementation changes. I never trust a side effect I didn't code myself. 8-)) Gary ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] Re: classes initialization
On 25 Mar 2008, at 14:40, L wrote: Not a fool proof test since random values have a chance of being zero, but it basically shows: 1. global old heap object NOT zeroed 2. local old heap object NOT zeroed 3. local class zeroed 4. global class zeroed The above terminology is wrong. Given your example procedure show; var rec: trec; c: tclass; o: tobj; po: pobj; begin ... What's on the stack is c (i.e., a pointer to a tclass instance) and po (a pointer to a tobj instance). Neither c nor po is automatically initialised with any value. Completely orthogonal to that is whether class instances or objects are initialised. As mentioned before, class instances are filled with zero. Object instances are just like any other data, so only fields of reference-counted types are initialised by the compiler. The class and object constructors have no clue where the actual instance is located (stack, heap, shared memory, ...) nor where the pointer to the instance (if any) will be stored, so that does have any influence on their behaviour. Jonas ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] Re: classes initialization
Jonas Maebe wrote: Using uninitialised variables is virtually always bad, regardless of the scope. And the fact that global variables are zeroed at the program start is afaik not defined by the Pascal standard. It's just a side effect of the way most operating systems work. I think I didn't get your point. What about this piece of code: interface function foo: tfoo; implementation var _foo: tfoo; function foo: tfoo; begin if not assigned(_foo) then _foo := tfoo.create; result := _foo; end; Is it safe? -- Joao Morais ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] Re: classes initialization
On 25 Mar 2008, at 14:21, Joao Morais wrote: Jonas Maebe wrote: Using uninitialised variables is virtually always bad, regardless of the scope. And the fact that global variables are zeroed at the program start is afaik not defined by the Pascal standard. It's just a side effect of the way most operating systems work. I think I didn't get your point. What about this piece of code: interface function foo: tfoo; implementation var _foo: tfoo; function foo: tfoo; begin if not assigned(_foo) then _foo := tfoo.create; result := _foo; end; Is it safe? It is safe on all currently supported targets (and we even go out of our way to ensure that it keeps working if global variables are turned into register variables), but it's still bad practice (and could in principle break one day, although it's unlikely given the backwards compatibility headaches that would cause). Jonas ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-pascal
[fpc-pascal] Re: classes initialization
Using uninitialised variables is virtually always bad, regardless of the scope. And the fact that global variables are zeroed at the program start is afaik not defined by the Pascal standard. It's just a side effect of the way most operating systems work. I think something like: procedure test; var blah: integer = 0; begin end; Is useful.. i.e. initialized variables that are done on the spot. And similarily a record could be: procedure test; var blah: TRec autoinit; begin end; This would allow safe programming without compromising backwards compatibility. But... in the mean time.. a solution is to make a standard record init procedure and do it like: procedure test; var blah: TRec; begin init(blah); end; Which will be what I use for now... And always do this by habit for safety now that I know this trick of the fillchar and such - only ever avoiding it when needing speed (but that is premature optimization). I realize that local scope uninitialized vars are the way systems work according to the system.. but we are humans and error prone humans...We can make languages safer I think and more consistent and human friendly at a higher level. Humans just make so many mistakes even though systems are supposed to work they way they are. i.e. really it is just a convenience and a standard good practice being now recommended right within the programming language...and more safety as an option. Just as I am also a fan of reference counted ansistrings versus using less safe pchars.. etc. ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-pascal
[fpc-pascal] Re: classes initialization
I wrote: I think something like: procedure test; var blah: integer = 0; begin end; Is useful.. i.e. initialized variables that are done on the spot. To expand on this.. not only local scope vars, but global.. var global: integer = 0; I agree is much clearer than leaving it to the assumption: // this will be zero.. bad assumption var global: integer; I wrote: And similarily a record could be: procedure test; var blah: TRec autoinit; begin end; This would be a good global habit to get into also for globals: var global: Trec autoinit; or var global: Trec; begin init(global) end; The problem with the above is that sometimes the global is further away in your code than you eyes can see, hence the inline declaring of initialization right while you are at it is safer for humans. Relying on global variables being zero is bad, I agree.. and they should be iniitalized by habit.. too. Especially when one copies global code into local code does a problem exist, if one made the assumption of the globals being initialized then (which may have been true, but now that they are no longer globals... problem time). ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-pascal
[fpc-pascal] Re: classes initialization
I wrote: 3. local class zeroed 4. global class zeroed I meant class instance zeroed (Regarding Jonas' nitpick ;-) ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-pascal
[fpc-pascal] Re: classes initialization
Joao Morais replied to Jonas with: I think I didn't get your point. What about this piece of code: interface function foo: tfoo; implementation var _foo: tfoo; function foo: tfoo; begin if not assigned(_foo) then _foo := tfoo.create; result := _foo; end; Is it safe? What about this: var _foo: tfoo = nil; That way you declare it right there and then.. ensuring it is not assigned. Hence why I think a good human practice is to always init everything even if it psychologically affects some people in ways such as will this slow the program down though? Do I need to init this stuff if I am going to init some of it later? which is evil premature optimization that causes bugs. L505 ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-pascal
[fpc-pascal] Re: classes initialization
Pascal does not define any variable initialization itself - one should always init all Pascal vars of any type. Doing so is an excellent coding habit also portable to any other language/OS - protects against low-level implementation changes. I never trust a side effect I didn't code myself. 8-)) We have to stop thinking in standard pascal and think about safety and ways to automate safety in a human matter. We are not computers, we are humans. You can claim all you want that you will ALWAYS init all your pascal vars... but you are a human and you will not *always* init all your pascal vars. This is the reason features like this have been available: var i: integer = 0; // handy procedure test; var i: integer = 0; // handy begin end; If you accidentally delete the init code and forget to put it back, the above way is safer. If you accidently init something in a dangerous way such as using FillChar on old code that now no longer works with the newer automated types.. again this is dangerous. It may be pascalish to continue to use hacks like FillChar and init() code far away from the declaration (especially in globals).. but this is the same as a C programmer saying that ansistrings are not C ish so we should use pchars all the time? Let's please stop the pascal fanboyism and consider humans, and safety. Even Wirth has moved away from pascal greatly if you study his languages Oberon, Modula, and a derived ComponentPascal. L505 ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-pascal