Lazarus

Free Pascal => General => Topic started by: FTurtle on December 28, 2017, 07:57:01 pm

Title: Class (static) fields of class. Initial values.
Post by: FTurtle on December 28, 2017, 07:57:01 pm
 
Code: Pascal  [Select][+][-]
  1.  TSomeClass = class
  2.   private class var
  3.     a: Pointer;
  4.   public
  5.     b: Pointer;
  6.   end;
  7.  

Situation for regular fields (b) is known.
I interesting on class (static) fields (a).
In fact after program is run, TSomeClass.a=nil
But I can't find it in FPC documentation.
So, the question:
Can I rely on the fact that after starting program TSomeClass.a=nil
Title: Re: Class (static) fields of class. Initial values.
Post by: molly on December 28, 2017, 08:13:14 pm
According to class variables documentation (https://www.freepascal.org/docs-html/ref/refsu24.html#x72-940006.2.2):
Quote
Similar to objects, a class can contain static fields or class variables: these fields or variables are global to the class, and act like global variables, but are known only as part of the class. They can be referenced from within the classes’ methods, but can also be referenced from outside the class by providing the fully qualified name.
Variable documentation (https://www.freepascal.org/docs-html/ref/refse24.html#x55-730004.4) states:
Quote
By default, simple variables in Pascal are not initialized after their declaration. Any assumption that they contain 0 or any other default value is erroneous: They can contain rubbish. To remedy this, the concept of initialized variables exists. The difference with normal variables is that their declaration includes an initial value, as can be seen in the diagram in the previous section.
and
Quote
Managed types are an exception to this rule: Managed types are always initialized: in general this means setting the reference count to zero, or setting the pointer value of the type to Nil. See section 3.9, page 215
Answer from documentation: it depends.
Title: Re: Class (static) fields of class. Initial values.
Post by: FTurtle on December 28, 2017, 09:07:44 pm
I read what you have quoted. It was the cause of question.
I'm cautious about phrases like "acts like" and their extrapolation.
I prefer explicit mentions.
I interesting simple types, so the answer is still "No".
But may be there is something what I don't know.
Title: Re: Class (static) fields of class. Initial values.
Post by: taazz on December 28, 2017, 09:16:30 pm
Correct. Even if the behavior is documented it is possible that the next version of the compiler will alter the initialization. It is far better to make sure that your static variables are initialized in what ever value you desire by setting it on the initialization section of the unit they are defined. I'm assuming that you do try to keep the static fields to a minimum.
Title: Re: Class (static) fields of class. Initial values.
Post by: Thaddy on December 28, 2017, 09:17:20 pm
Well let me spell it out:  So yes, the class var is nil. And that is as per the documentation.
Title: Re: Class (static) fields of class. Initial values.
Post by: FTurtle on December 28, 2017, 10:22:20 pm
I'm assuming that you do try to keep the static fields to a minimum.

The goal is to hide global typed constant used in single method.
First I wished make it as static field but finally I just moved  it inside method.
This solution even is better because we immediately see that identifier is used nowhere else.

Well let me spell it out:  So yes, the class var is nil. And that is as per the documentation.

It would be good if you could provide a link.
Title: Re: Class (static) fields of class. Initial values.
Post by: PascalDragon on January 02, 2018, 10:47:22 pm
Well let me spell it out:  So yes, the class var is nil. And that is as per the documentation.

Yes and no. Yes: As of now for all targets FPC supports global variables (and static variables) are initialized to 0, but that is not guaranteed by the compiler, but by the OS, so if the OS decides not to do it then it won't be! That is also why we do not document this (thus the No).
Title: Re: Class (static) fields of class. Initial values.
Post by: Thaddy on January 02, 2018, 11:23:35 pm
Well let me spell it out:  So yes, the class var is nil. And that is as per the documentation.

Yes and no. Yes: As of now for all targets FPC supports global variables (and static variables) are initialized to 0, but that is not guaranteed by the compiler, but by the OS, so if the OS decides not to do it then it won't be! That is also why we do not document this (thus the No).

UUhhh.... In trunk.... See... http://wiki.freepascal.org/management_operators ...  :P
Title: Re: Class (static) fields of class. Initial values.
Post by: hnb on January 03, 2018, 09:47:49 am
UUhhh.... In trunk.... See... http://wiki.freepascal.org/management_operators ...  :P
Finally we have some documentation for management operators.  :o  thanks.
Title: Re: Class (static) fields of class. Initial values.
Post by: Thaddy on January 03, 2018, 11:52:47 am
UUhhh.... In trunk.... See... http://wiki.freepascal.org/management_operators ...  :P
Finally we have some documentation for management operators.  :o  thanks.
Now get that default in, Maciej (and Sven..). Happy New Year.

Feel free to edit: I simply made some small examples and used the notes from the feature announcement.
I still need to add some more examples, I guess. (like a powerful debugging tool in just a few lines...)

Regards,

Thaddy
Title: Re: Class (static) fields of class. Initial values.
Post by: PascalDragon on January 05, 2018, 04:02:35 pm
Well let me spell it out:  So yes, the class var is nil. And that is as per the documentation.

Yes and no. Yes: As of now for all targets FPC supports global variables (and static variables) are initialized to 0, but that is not guaranteed by the compiler, but by the OS, so if the OS decides not to do it then it won't be! That is also why we do not document this (thus the No).

UUhhh.... In trunk.... See... http://wiki.freepascal.org/management_operators ...  :P

Records with management operators have explicit initializers and finalizers that are called by the RTL just like for any other managed types. This does in no way change how variables of primitive types or records without management operators behave. In fact the initial value of a managed type (String, interface, record with management operators) can be considered as undefined before the initialization code is run and that does include global variables.
So this changes nothing at all regarding what I said. In addition to that the official, sanctioned documentation is at http://www.freepascal.org/docs.var (http://www.freepascal.org/docs.var), so even if anyone would add a wiki entry with "globals are always initialized to 0" that would in no way be considered as binding.
Title: Re: Class (static) fields of class. Initial values.
Post by: ASerge on January 05, 2018, 06:37:15 pm
Yes and no. Yes: As of now for all targets FPC supports global variables (and static variables) are initialized to 0, but that is not guaranteed by the compiler, but by the OS, so if the OS decides not to do it then it won't be! That is also why we do not document this (thus the No).
Now the compiler generates code for placing global variables using the .bss section, which by definition is zeroed, and also explicitly indicates this.
For this
Code: Pascal  [Select][+][-]
  1. program Project1;
  2.  
  3. var
  4.   S: string;
  5.   N: Integer;
  6. begin
generate
Code: ASM  [Select][+][-]
  1. .section .bss
  2.         .balign 8
  3. # [project1.lpr]
  4. # [4] S: string;
  5. U_$P$PROJECT1_$$_S:
  6.         .zero 8
  7.  
  8. .section .bss
  9.         .balign 4
  10. # [5] N: Integer;
  11. U_$P$PROJECT1_$$_N:
  12.         .zero 4
And for global variables of managed types, no additional code is generated for zeroing.
So the compiler knows for sure that global variables are zeroed.
Title: Re: Class (static) fields of class. Initial values.
Post by: Thaddy on January 05, 2018, 06:53:55 pm
Sven is correct: this is even now not always the case. E.g. Someone can override newinstance and you are screwed.
You merely demonstrate current behavior. Sven falsified it. (see my autograph)
Title: Re: Class (static) fields of class. Initial values.
Post by: PascalDragon on January 10, 2018, 11:36:23 am
Yes and no. Yes: As of now for all targets FPC supports global variables (and static variables) are initialized to 0, but that is not guaranteed by the compiler, but by the OS, so if the OS decides not to do it then it won't be! That is also why we do not document this (thus the No).
Now the compiler generates code for placing global variables using the .bss section, which by definition is zeroed, and also explicitly indicates this.

But we do not guarantee that a .bss section is used for all platforms. Thus global variables are not guaranteed to be initialized to a specific value (and managed variables are only guaranteed a specific value after their initialization code is run).
Title: Re: Class (static) fields of class. Initial values.
Post by: ASerge on January 10, 2018, 03:39:24 pm
Thus global variables are not guaranteed to be initialized to a specific value (and managed variables are only guaranteed a specific value after their initialization code is run).
Repeat "...And for global variables of managed types, no additional code is generated for zeroing". The compiler (not the OS) knows that it is not required to zeroed them.
Title: Re: Class (static) fields of class. Initial values.
Post by: Thaddy on January 10, 2018, 04:12:49 pm
Repeat "...And for global variables of managed types, no additional code is generated for zeroing". The compiler (not the OS) knows that it is not required to zeroed them.
What about stack? Stackspace is dirty by default.What about longstrings that are part of a class or record? What about code where the initialization is overridden (e.g. newinstance is virtual)? You are making assumptions that are nor always true.
And it is not always the compiler, but the runtime library that initializes memory through InitInstance, which in turn can be skipped in newinstance.
This is only the scenario for classes. With managed objects and managed records - that are now supported - it is even more dangerous to rely on such an assumption: e.g. New() does getmem (dirty), not allocmem(clean).

You should assume *nothing* about initialization and even ignore some current behavior that you happen to think to know about the current implementation.

BTW: This is also true for Delphi: at least before XE2 and higher, compiling.debugging in the IDE cleans all heap memory, but not when running a program outside the IDE: behavior is not to clean the heap unless initinstance (which happens to AllocMem..implementation detail)is called, and that is not guaranteed..
Quote
The compiler (not the OS) knows that it is not required to zeroed them.
Is therefor nonsense. This is a programmer's task, not a compiler's task. Class fields or not: they can not be assumed to be clean.
Title: Re: Class (static) fields of class. Initial values.
Post by: PascalDragon on January 13, 2018, 01:50:51 pm
Thus global variables are not guaranteed to be initialized to a specific value (and managed variables are only guaranteed a specific value after their initialization code is run).
Repeat "...And for global variables of managed types, no additional code is generated for zeroing". The compiler (not the OS) knows that it is not required to zeroed them.
But the compiler would generate such code if we had a target that does not support something akin to .bss. Case in point is that it does generate initialization calls for records with management operators cause it does not know what the code in there does with the record. For the other primitive types the compiler knows that they are to be initialized to 0/Nil and thus does not need to do anything on a target that does support .bss.
TinyPortal © 2005-2018