Guaranteed Zero

User avatar
DGDanforth
Posts: 1061
Joined: Tue Sep 17, 2013 1:16 am
Location: Palo Alto, California, USA
Contact:

Re: Guaranteed Zero

Post by DGDanforth »

Code: Select all

MODULE MyZeros;	(*Set record memory to zero*)

	IMPORT
		Meta,
		S:=SYSTEM;

(*
*)
	PROCEDURE Zero* (IN modName, recName: ARRAY OF CHAR; VAR r: ANYREC);
	VAR size: INTEGER; mod, item: Meta.Item; byte: BYTE; a0:INTEGER;
	BEGIN
		Meta.Lookup(modName, mod);
		mod.Lookup(recName, item);
		IF item.Valid() THEN
			size := item.Size();
			a0 := S.ADR(r);
			byte := 0;
			S.PUT(a0, byte);
			S.MOVE(a0, a0+1, size-1);
		END
	END Zero;
	
END MyZeros.

Code: Select all

MODULE TestMyZeros;	

	IMPORT
		Out:=MyOut,
		Z:=MyZeros;
		
	TYPE
		Record* =	RECORD
				bool:	BOOLEAN;
				shortchar:	SHORTCHAR;
				char:	CHAR;
				byte:	BYTE;
				shortint:	SHORTINT;
				int:	INTEGER;
				longint:	LONGINT;
				shortreal:	SHORTREAL;
				real:	REAL;
				set:	SET
			END;
		Big* =	RECORD
				x:	ARRAY ASH(2, 16) OF BYTE
			END;
	VAR
		level:	INTEGER;
		zero:	BOOLEAN;
(*
*)
	PROCEDURE (VAR r: Record) Out (IN banner: ARRAY OF CHAR), NEW;
	BEGIN
		Out.Ln; Out.String(banner); Out.Ln;
		Out.String("bool="); Out.Bool(r.bool); Out.Ln;
		Out.String("shortchar="); Out.Char(r.shortchar); Out.Ln;
		Out.String("char="); Out.Char(r.char); Out.Ln;
		Out.String("byte="); Out.Int(r.byte); Out.Ln;
		Out.String("shortint="); Out.Int(r.shortint); Out.Ln;
		Out.String("int="); Out.Int(r.int); Out.Ln;
		Out.String("longint="); Out.Int(r.longint); Out.Ln;
		Out.String("shortreal="); Out.Real(r.shortreal); Out.Ln;
		Out.String("real="); Out.Real(r.real); Out.Ln;
		Out.String("set="); Out.Set(r.set); Out.Ln;
	END Out;
	
	PROCEDURE Do*;
	VAR
		rec:	Record;
	BEGIN
		rec.Out("Before");
		Z.Zero("TestMyZeros", "Record", rec);
		rec.Out("After");
	END Do;
	
	PROCEDURE Recurse;
	VAR
		big:	Big;
	BEGIN
		IF level > 0 THEN
			IF zero THEN Z.Zero("TestMyZeros", "Big", big) END;
			DEC(level);
			Recurse
		END
	END Recurse;

	PROCEDURE Time*;
	BEGIN
		level := 10;
		zero := TRUE;
		Recurse;
	END Time;

END TestMyZeros.

@ TestMyZeros.Do
@ TestMyZeros.Time
@  "TboxTimer.Start; TestMyZeros.Time; TboxTimer.Stop"
User avatar
DGDanforth
Posts: 1061
Joined: Tue Sep 17, 2013 1:16 am
Location: Palo Alto, California, USA
Contact:

Re: Guaranteed Zero

Post by DGDanforth »

Caveat:
I just realized that my analysis is bogus, wanting.

Since every variable must be 'set' before 'used' the amount of time needed
to run a program would the equal to (or greater) for uninitialized variables
as for blanket initialization to zero. The time would be greater if the time to access individual
fields of a record is greater than zeroing the whole record.

Hence the issue returns to whether '0' is the correct initialization value.
If one wants a variable to be 13 initially then zeroing it and then setting it to 13 is double the time (approx).

Josef said
"In ETH Oberon one argument was that binary zero initialization may not be appropriate
for some values on some platforms, e.g. pointers if NIL is represented as something
other than binary 0. Also floats could be initialized to the value 'undefined' instead of 0.
There is also the question if the zero-initialization is a compiler property or if it
is defined in the language."

But "on some platforms" makes BB non portable. By having one and only one value defined for (in this case) NIL the issue of platform goes away.

Why should floats be initialized to 'undefined'? Are you saying that one simply takes the hardware representation of float as its initial value? I would think that is a bad idea where again one wants a platform independent implementation so that one can 'write once, run everywhere'.

I am back to advocating "Guaranteed ZERO". The run times will be comparable for machine initialization and hand initialization. It is only slower for those variables whose initial values are 'non standard'.
Ivan Denisov
Posts: 1700
Joined: Tue Sep 17, 2013 12:21 am
Location: Russia

Re: Guaranteed Zero

Post by Ivan Denisov »

Doug, there are no "standart values". For each task "standart" is different.

Can you share the modified Kernel?
User avatar
DGDanforth
Posts: 1061
Joined: Tue Sep 17, 2013 1:16 am
Location: Palo Alto, California, USA
Contact:

Re: Guaranteed Zero

Post by DGDanforth »

Ivan Denisov wrote:Doug, there are no "standart values". For each task "standart" is different.

Can you share the modified Kernel?
I have not created a modified Kernel. I used the code presented above.

My comment about "standard values" was slightly facetious (treating serious issues with deliberately inappropriate humor; flippant).

I would find it useful to examine a large body of code to see the percentage of variables whose initial values deviate from ZERO.
cfbsoftware
Posts: 204
Joined: Wed Sep 18, 2013 10:06 pm
Contact:

Re: Guaranteed Zero

Post by cfbsoftware »

DGDanforth wrote:Why should floats be initialized to 'undefined'?
The same reason why pointers should be initialized to NIL. The intention is to make it possible to quickly detect when a programmer has forgotten to initialize a variable - not to save him the bother of initialising variables. Setting all variables to zero does not correct the problem of programmer forgetfulness if the required value is non-zero. Even worse, initialising values to zero may make it take longer to detect forgetfulness because using zero is more likely to hide a problem than, say, an extremely large number which might be more easily spotted during testing.

When pointers are initialised to NIL runtime error trapping will immediately detect when a pointer is misused. Any other value for a pointer could be valid.

Similarly, if floats are initialised to undefined, assertions or runtime error trapping can detect if the programmer has forgotten to set them to a valid value (which may be 0.0 or it may be 3.1414, or some other value).

The problem with initialising integers to zero is that zero might be a valid value so it is impossible to detect if the programmer has made a mistake. Unfortunately, there is no such thing as an invalid integer that could be used to initialise integers. The next best thing might be -0 i.e. 080000000H but even this oddball number has valid uses.
User avatar
DGDanforth
Posts: 1061
Joined: Tue Sep 17, 2013 1:16 am
Location: Palo Alto, California, USA
Contact:

Re: Guaranteed Zero

Post by DGDanforth »

Chris,
I am still not persuaded.

With ZERO as the default value the mind set of the programmer changes.
A floating point with zero value is expected. If that is a valid value in a situation
then so be it. If it should be some other value but the programmer forgets
to set it then he gets what he gets.

So we have two conflicting principles: fail as soon as possible; and ZERO is the default value.

The pointer set to NIL is a specious argument for fail as soon as possible because NIL may be
exactly what a programmer wants the value to be. IF p=NIL THEN ... END

If one wishes to 'guarantee' failure for all uninitialized data types then the language should support an 'initialized' attribute for each type in the same way that back pointers exist for referencing fields of a record when only a pointer to the record is provided. If every INTEGER had one byte preceding the address of the integer whose value specified whether the integer had been set then the fail as soon as possible would apply for integers (as well as all of the other data types). The overhead would be the cost of checking the byte on every access to the data type. But, I assume, there is already that cost for checking pointer NIL values.

-Doug
User avatar
DGDanforth
Posts: 1061
Joined: Tue Sep 17, 2013 1:16 am
Location: Palo Alto, California, USA
Contact:

Re: Guaranteed Zero

Post by DGDanforth »

Now this is interesting.
One of the things I learned while working for Tymeshare back in 1978 was not to use the value of a variable as a special case but rather to use a separate variable to indicate the special case. In that way all values of the first variable are valid and useable. That is what I suggested for the 'init byte' posted above.

So what should be the initial value of the init byte o:) ? I would think it should be 0 (for all data types).
Testing the init byte would only require 2 or 3 additional machine instruction when a variable is accessed (read) and similarly when it is written (assigned) to set the init byte. Variables allocated would set the init byte to zero, a tiny overhead as compared to clearing a whole array of memory.

So I believe an init byte would satisfy both the requirements of 'fail as soon as possible' and 'Guaranteed ZERO' where now that condition is modified so that the user can test the init byte and zero memory if so desired.
Post Reply