Hi, Just some technical background to this discussion, I don't care who documented what, I'm just stating how it works. :P
On Thu, 5 Apr 2018, Ondrej Pokorny wrote: > >>> Now, it is also correct that the compiler developers are aware that > >>> many people rely on this implementation detail. > >> > >> Since when is documented behavior considered as "implementation > >> detail"? This is not an implementation detail. It is in official > >> documentation. > > > > You and I know very well that this is an implementation detail, needed > > for internal bookkeeping of the compiler. That the delphi manual states > > otherwise, I have always considered a grave error on their part: > > It contradicts one of the core tenets of pascal - see below. The Delphi manual probably states the de-facto behavior. You cannot not initialize global variables to zero on most modern Un*ces and Windows, because the OS will zero out the bss section on executable loading, which is where most global variables live. (Unless they're in the data section, in which case they have a specified initial value, but that's more like typed consts with an initial value in Pascal's context.) But again, it's zeroed out, not really "initialized". So for example if you have a type with say, 5..7 value range, it will still contain zero after start. Hence, uninitialized, therefore the warning is correct. (See below for examples.) > Huh, no, I don't know this is an implementation detail. For me the > initialization rules always were: > > 1.) Global variables are initialized. (Why is simple global variables > initialization needed for internal bookkeeping of the compiler?) As I wrote above, we cannot not "initialize" (as in: zero out) the global variables on modern systems, because the compiler doesn't do it, but the executable loader of the OS. (Well, it's actually a bit more complicated, if threadvars are involved, but that's platform specific what happens there, and the end result is the same - global variables are zeroed out.) > 2.) Class fields are initialized. (Why is simple class fields > initialization needed for internal bookkeeping of the compiler?) I think this is something which happens when constructing the class, so this is runtime behavior, and not compile or exe loading time, and again, it's just clearing the allocation after GetMem()'ing the heap area for the class, so you don't get trash in the fields. But they're don't necessarily initialized to valid values (if zero is not valid). > 3.) Everything else is not initialized. > Yes, I have always relied on both 1.+2. For me both points 1.+2. are > well documented and wanted behavior. Isn't it so? Do you want initialized, or zeroed out? Zero out will happen, initialization will not: Take these two examples: type qq = (foo, bar, klepp, mopp, fubb); q = klepp..fubb; var c: q; begin writeln(ord(c)); // will write 0; writeln(c); // will fail with runtime error (out of range) end. And: {$MODE OBJFPC} type qq = (foo, bar, klepp, mopp, fubb); q = klepp..fubb; type clfoo = class c: q; end; var x: clfoo; begin x:=clfoo.create; writeln(ord(x.c)); // write 0; writeln(x.c); // runtime error (out of range) end. Tested with FPC 3.0.4 32bit on macOS. I'd be interesting to know if Delphi behaved otherwise. But in the above case the compiler warning about uninitialized variable is completely valud, even if it's not random but initialized to zero due to OS and RTL behavior. Charlie _______________________________________________ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel