Page 1 of 2

Guaranteed Zero

Posted: Sun Aug 03, 2014 2:17 am
by DGDanforth
From the CP Language Reference

"All fields or elements of a newly allocated record or array are cleared, which implies that all embedded pointers and procedure variables are initialized to NIL"
and
"Local variables whose types are pointer types or procedure types are initialized to NIL before the body of the procedure is executed."

...but the other local variables are NOT initialized. I think that is a poor language design choice. For example, a record with a BOOLEAN variable which occurs as a local record is not guaranteed to have the value FALSE when first accessed. That necessitates the record implement a method to initialize its variables. I recently kludged a solution for the BOOLEAN case by changing that variable to a pointer type with no fields. The pointer is guaranteed to be NIL on first access within a local declaration of the record. I should not have had to do that.

PROPOSAL
Change Component Pascal to guaranteed that local variables are initialized to ZERO before the body of the procedure is executed where ZERO is defined for all basic data types

Code: Select all

TYPE                  ZERO
BOOLEAN               FALSE
CHAR                  0X
INTEGER               0
REAL                  0.0
SET                   {}
ARRAY OF CHAR         ""
POINTER               NIL
That can easily by implemented with a bitblt of memory.
I request that we include 'Guaranteed ZERO' in our next release of BlackBox.

-Doug Danforth

Re: Guaranteed Zero

Posted: Sun Aug 03, 2014 8:01 am
by cfbsoftware
DGDanforth wrote:Change Component Pascal to guaranteed that local variables are initialized to ZERO before the body of the procedure is executed where ZERO is defined for all basic data types
NO - That is a bad idea for several reasons including diminished fault-finding capabilities, reliability and performance. The omission of such a 'feature' was not a design oversight. The basic wrong assumption here is that zero, FALSE etc. are correct initial values. It only makes sense for pointers because a NIL value allows BlackBox to flush out the runtime error when the programmer subsequently forgets to initialise it with the correct value.

The suggestion has arisen from time to time in Oberon and Component Pascal discussions. My response in one such discussion is here:

http://blackboxframework.org/archive/2008/5042.html

Re: Guaranteed Zero

Posted: Mon Aug 04, 2014 2:23 am
by DGDanforth
cfbsoftware wrote:
DGDanforth wrote:Change Component Pascal to guaranteed that local variables are initialized to ZERO before the body of the procedure is executed where ZERO is defined for all basic data types
NO - That is a bad idea for several reasons including diminished fault-finding capabilities, reliability and performance. The omission of such a 'feature' was not a design oversight. The basic wrong assumption here is that zero, FALSE etc. are correct initial values. It only makes sense for pointers because a NIL value allows BlackBox to flush out the runtime error when the programmer subsequently forgets to initialise it with the correct value.

The suggestion has arisen from time to time in Oberon and Component Pascal discussions. My response in one such discussion is here:

http://blackboxframework.org/archive/2008/5042.html
Sorry but I disagree. Why is a random value better than zero? I used the MAINSAIL programming language for 14 years which guaranteed all data types are initialized to ZERO. It worked (works) just fine. MAINSAIL is Machine Independent SAIL where SAIL is Stanford AI Language which is an Algol based language (such as Algol-W, i.e. Wirth).

If M is the total size of all local variables for a procedure then M amount of memory must be allocated for it on the stack. If some of those variables are pointers then the compiler must know that and initialize them to zero. That takes a bit of code to do that. If instead all of M is cleared then a single blt of memory can be used and no specific pointer code need occur. Much cleaner and conceptually simpler.

"If we talk about second, students can be much surprised, when
their algorithms in one events works, but in other no"

Random (lack of) initialization can lead to random behavior.

-Doug

Re: Guaranteed Zero

Posted: Mon Aug 04, 2014 3:14 am
by Ivan Denisov
If this hidden initialisation will decrease the performance of all blackbox programms this is not good idea.
Chris Burrows wrote:Gardens Point implementation of Component Pascal. Their compiler does very
thorough program flow analysis and is able to warn at compile time if a
value is not initialised.
DevAnalyzer.Analyze is warning about such cases.
warning.png
warning.png (12.59 KiB) Viewed 14653 times

Re: Guaranteed Zero

Posted: Mon Aug 04, 2014 3:29 am
by DGDanforth
Ivan Denisov wrote:If this hidden initialisation will decrease the performance of all blackbox programms this is not good idea.
Chris Burrows wrote:Gardens Point implementation of Component Pascal. Their compiler does very
thorough program flow analysis and is able to warn at compile time if a
value is not initialised.
Dev->Analyzer warns about such cases.
Maybe, but how much? That is an empirical question that needs testing.
Putting ASSERT into programs also decreases performance but greatly increases the reliability
of the programs. Using ZERO also increases the reliability of programs.

Re: Guaranteed Zero

Posted: Mon Aug 04, 2014 3:58 am
by Ivan Denisov
With ASSERTS and POINTERS you have a choice to use them or not to use in critical places. The same need to be with your suggested feature, like an flag during the compilation of the Kernel or some compiler option. In that case I think, that it can be implemented, however this will lead to the two different programming styles, that will make difficult analisis of sources.

The best way, from my point of view, is to add one more procedure key [zero].

Code: Select all

PROCEDURE [zero] GuaranteedFalse;
VAR isDone: BOOLEAN;
BEGIN
   Log.Bool(isDone);
END GuaranteedFalse;

Re: Guaranteed Zero

Posted: Mon Aug 04, 2014 7:02 am
by DGDanforth
Ivan Denisov wrote:With ASSERTS and POINTERS you have a choice to use them or not to use in critical places. The same need to be with your suggested feature, like an flag during the compilation of the Kernel or some compiler option. In that case I think, that it can be implemented, however this will lead to the two different programming styles, that will make difficult analisis of sources.

The best way, from my point of view, is to add one more procedure key [zero].

Code: Select all

PROCEDURE [zero] GuaranteedFalse;
VAR isDone: BOOLEAN;
BEGIN
   Log.Bool(isDone);
END GuaranteedFalse;
Hmm, interesting but...every procedure would have to be so marked (at least I would want that to be the case). A compiler switch would be a better solution. I am advocating the programming style that relies on guaranteed zero. I think that is a much better style that should be taught rather than random values of variables.

I will try and implement, in a branch, the ZERO initialization. I have looked briefly at the kernel and standard loader. I will be the first to abandon that approach if program execution time increases by more than, say, 5%.
-Doug

Re: Guaranteed Zero

Posted: Mon Aug 04, 2014 9:11 am
by Josef Templ
in Java and C# there is a different approach being taken.
Local variables are not automatically initialized but there is
a compile time check for using uninitialized variables.
In Java this kind of check is particularly simple because of the
simple type system (no VAR parameters, no struct/array on the stack).
In both platforms there is no runtime overhead for those checks.

In BlackBox this check can be performed by DevAnalyzer, which does a good job
but cannot find all the problems.

Introducing an automatic zero-initialization in CP may be expensive
in terms of memory accesses even if the code is short. The memory interface
is the main bottleneck in modern CPUs. I would not recommend to do it
although it also happened to me that I used an uninitialized variable.

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.
So, in order to keep it simple, efficient and portable there was no zero-initialization.

- Josef

Re: Guaranteed Zero

Posted: Mon Aug 04, 2014 11:37 pm
by DGDanforth
Thank you Josef.

I ran a test program where (instead of modifying the Kernel) I created a Zero procedure
that operates on ANYREC using a combination of Meta and SYSTEM. I used the
SYSTEM.MOVE operation to zero memory of a record. That worked.

I then wrote a test harness using recursion of a big record (2^16 bytes) to a depth of 10
(stack overflow occurs for deeper depth). I timed the recursion (using TboxTimer) with and
without zeroing memory. The difference was substantial: without zeroing time = 0ms,
with zeroing time=10ms.

Hence I withdraw my request for "Guaranteed ZERO".
I will more judiciously use DevAnalyzer.

-Doug

Re: Guaranteed Zero

Posted: Tue Aug 05, 2014 4:17 am
by Ivan Denisov
Doug, please, share the tests here or in a test branch.