www.digitalmars.com         C & C++   DMDScript  

D - NaN initializers for floating point?

reply "Ben Hinkle" <bhinkle mathworks.com> writes:
Why is NaN the default value for floats and doubles? The most common desired
behavior is to default to 0. If the point of initializers is to make sure
you specify an initial value in user code then NaN is fine because you
almost never want to start a computation with NaN but if the point is to
make a convenient default value then I'd suggest going with 0. It would also
improve ease-of-use because every language I can think of that has defaults
uses 0.

just a thought,
-Ben
Jan 18 2003
next sibling parent reply "Walter" <walter digitalmars.com> writes:
"Ben Hinkle" <bhinkle mathworks.com> wrote in message
news:b0c0n3$1jaj$1 digitaldaemon.com...
 Why is NaN the default value for floats and doubles? The most common
desired
 behavior is to default to 0. If the point of initializers is to make sure
 you specify an initial value in user code then NaN is fine because you
 almost never want to start a computation with NaN but if the point is to
 make a convenient default value then I'd suggest going with 0. It would
also
 improve ease-of-use because every language I can think of that has
defaults
 uses 0.
The reason is to cause the programmer to think about what the initial value should be. 0 is usually what is desired, but 1, pi, etc., are also candidates. Using NaN means that if you didn't specify one, and the result of the computation relies on it, the result would be NaN. If it were possible for NaNs for integers, I'd have used that too.
Jan 18 2003
next sibling parent reply Mark Evans <Mark_member pathlink.com> writes:
Walter here I would toss back at you the hoary old chestnut you toss at me when
I suggest D features that don't feel like C.

Using a NaN initializer may be theoretically and pedagogically proper but it's
dumb because nobody expects it.  Zero is the value to use.

Mark

The reason is to cause the programmer to think about what the initial value
should be. 0 is usually what is desired, but 1, pi, etc., are also
candidates. Using NaN means that if you didn't specify one, and the result
of the computation relies on it, the result would be NaN. If it were
possible for NaNs for integers, I'd have used that too.
Jan 18 2003
parent reply "Walter" <walter digitalmars.com> writes:
"Mark Evans" <Mark_member pathlink.com> wrote in message
news:b0cbcb$1q0i$1 digitaldaemon.com...
 Walter here I would toss back at you the hoary old chestnut you toss at me
when
 I suggest D features that don't feel like C.
Fair enough!
 Using a NaN initializer may be theoretically and pedagogically proper but
it's
 dumb because nobody expects it.  Zero is the value to use.
The nice thing about NaN is it won't bite you if you don't expect it. 0 will.
Jan 18 2003
parent reply "Sean L. Palmer" <seanpalmer directvinternet.com> writes:
Oftentimes I'd rather have a zero.  We chase NaN's all the time at work.
Someone takes acos(1.00000001) and poof you get a NaN.  I can't imagine the
kind of NaN hell you'd be in if it was the default value.  It'll be biting
people all the time.  If you run statistics it'll likely be the single
largest source of runtime bugs in D.  Mark my words.  Ok maybe the C-style
case fallthru will be a close second.  ;)  If a NaN creeps in anywhere in a
system, all hell breaks loose with NaN's propagating everywhere until the
whole system blows up.  In our game, that causes the player to disappear and
the screen to flash wildly;  everything goes nuts.   All it takes is one NaN
hiding somewhere in a rarely-used variable to wreak havok.  I'd rather have
the compiler just force me to initialize everything explicitly.

Sean

"Walter" <walter digitalmars.com> wrote in message
news:b0ch22$1tnk$2 digitaldaemon.com...
 "Mark Evans" <Mark_member pathlink.com> wrote in message
 news:b0cbcb$1q0i$1 digitaldaemon.com...
 Walter here I would toss back at you the hoary old chestnut you toss at
me
 when
 I suggest D features that don't feel like C.
Fair enough!
 Using a NaN initializer may be theoretically and pedagogically proper
but
 it's
 dumb because nobody expects it.  Zero is the value to use.
The nice thing about NaN is it won't bite you if you don't expect it. 0 will.
Jan 19 2003
parent reply Russell Lewis <spamhole-2001-07-16 deming-os.org> writes:
Sean L. Palmer wrote:
 Oftentimes I'd rather have a zero.  We chase NaN's all the time at work.
 Someone takes acos(1.00000001) and poof you get a NaN.  I can't imagine the
 kind of NaN hell you'd be in if it was the default value.  It'll be biting
 people all the time.  If you run statistics it'll likely be the single
 largest source of runtime bugs in D.  Mark my words.  Ok maybe the C-style
 case fallthru will be a close second.  ;)  If a NaN creeps in anywhere in a
 system, all hell breaks loose with NaN's propagating everywhere until the
 whole system blows up.  In our game, that causes the player to disappear and
 the screen to flash wildly;  everything goes nuts.   All it takes is one NaN
 hiding somewhere in a rarely-used variable to wreak havok.  I'd rather have
 the compiler just force me to initialize everything explicitly.
It's true that a NaN *could* hide somewhere in the code, but it's not terribly likely. Certainly, a 0 has more chance of hiding itself all the way into production code than a NaN does.
Jan 21 2003
parent "Sean L. Palmer" <seanpalmer directvinternet.com> writes:
"Russell Lewis" <spamhole-2001-07-16 deming-os.org> wrote in message
news:3E2DC40F.2030001 deming-os.org...
 Sean L. Palmer wrote:
 Oftentimes I'd rather have a zero.  We chase NaN's all the time at work.
 Someone takes acos(1.00000001) and poof you get a NaN.  I can't imagine
the
 kind of NaN hell you'd be in if it was the default value.  It'll be
biting
 people all the time.  If you run statistics it'll likely be the single
 largest source of runtime bugs in D.  Mark my words.  Ok maybe the
C-style
 case fallthru will be a close second.  ;)  If a NaN creeps in anywhere
in a
 system, all hell breaks loose with NaN's propagating everywhere until
the
 whole system blows up.  In our game, that causes the player to disappear
and
 the screen to flash wildly;  everything goes nuts.   All it takes is one
NaN
 hiding somewhere in a rarely-used variable to wreak havok.  I'd rather
have
 the compiler just force me to initialize everything explicitly.
It's true that a NaN *could* hide somewhere in the code, but it's not terribly likely. Certainly, a 0 has more chance of hiding itself all the way into production code than a NaN does.
Which is why I think the compiler should deal with uninitialized variables as an error condition; force the programmer to put something sensible into them. Sure they'll still insert bogus values occasionally, but at least you won't get garbage or NaN. It's a minor inconvenience compared to the headaches it would save. Too bad Walter seems philosophically opposed to it. Sean
Jan 22 2003
prev sibling next sibling parent reply "Ben Hinkle" <bhinkle mathworks.com> writes:
"Walter" <walter digitalmars.com> wrote in message
news:b0c6pk$1n6b$1 digitaldaemon.com...
 "Ben Hinkle" <bhinkle mathworks.com> wrote in message
 news:b0c0n3$1jaj$1 digitaldaemon.com...
 Why is NaN the default value for floats and doubles? The most common
desired
 behavior is to default to 0. If the point of initializers is to make
sure
 you specify an initial value in user code then NaN is fine because you
 almost never want to start a computation with NaN but if the point is to
 make a convenient default value then I'd suggest going with 0. It would
also
 improve ease-of-use because every language I can think of that has
defaults
 uses 0.
The reason is to cause the programmer to think about what the initial
value
 should be. 0 is usually what is desired, but 1, pi, etc., are also
 candidates. Using NaN means that if you didn't specify one, and the result
 of the computation relies on it, the result would be NaN. If it were
 possible for NaNs for integers, I'd have used that too.
Could you throw a compile-time warning when floats or doubles aren't explicitly initialized? Throwing a compile-time error would be harsh but a warning would save me from debugging the problem at run-time. At least a NaN isn't as nasty to debug as random uninitialized memory :)
Jan 18 2003
next sibling parent "Walter" <walter digitalmars.com> writes:
"Ben Hinkle" <bhinkle mathworks.com> wrote in message
news:b0cc2q$1qh0$1 digitaldaemon.com...
 Could you throw a compile-time warning when floats or doubles aren't
 explicitly initialized?
I considered that, but my experience with C/C++ compilers that did that is rather negative. It results in lots of useless initializations put in just to shut the compiler up. I am philosophically opposed to requiring initializers when such values are never used - it confuses the person maintaining the code.
 Throwing a compile-time error would be harsh but a
 warning would save me from debugging the problem at run-time. At least a
NaN
 isn't as nasty to debug as random uninitialized memory :)
NaNs are a lot easier to track down than an unintended 0.
Jan 18 2003
prev sibling parent reply "Walter" <walter digitalmars.com> writes:
"Ben Hinkle" <bhinkle mathworks.com> wrote in message
news:b0cc2q$1qh0$1 digitaldaemon.com...
 Could you throw a compile-time warning when floats or doubles aren't
 explicitly initialized? Throwing a compile-time error would be harsh but a
 warning would save me from debugging the problem at run-time. At least a
NaN
 isn't as nasty to debug as random uninitialized memory :)
Another thing about NaNs is they'll make it clear that you've got a bug. A default 0 initialization can hide a bug, and such hidden bugs were one of the incentives to introduce NaNs.
Jan 18 2003
parent reply "Robert M. Münch" <robert.muench robertmuench.de> writes:
"Walter" <walter digitalmars.com> schrieb im Newsbeitrag
news:b0dh74$2dc3$1 digitaldaemon.com...

 Another thing about NaNs is they'll make it clear that you've got a bug. A
 default 0 initialization can hide a bug, and such hidden bugs were one of
 the incentives to introduce NaNs.
Absolutly right! I stumbled about the NaN semantics too but IMO Walter took the right way. 0 is a number with mathematic semantics, NaN is not. No semantics --> no result is a good and easy rule. Robert
Jan 20 2003
parent "Walter" <walter digitalmars.com> writes:
"Robert M. Münch" <robert.muench robertmuench.de> wrote in message
news:b0gsl2$13d7$1 digitaldaemon.com...
 "Walter" <walter digitalmars.com> schrieb im Newsbeitrag
 news:b0dh74$2dc3$1 digitaldaemon.com...
 Another thing about NaNs is they'll make it clear that you've got a bug.
A
 default 0 initialization can hide a bug, and such hidden bugs were one
of
 the incentives to introduce NaNs.
Absolutly right! I stumbled about the NaN semantics too but IMO Walter
took
 the right way. 0 is a number with mathematic semantics, NaN is not. No
 semantics --> no result is a good and easy rule. Robert
Years ago, early in my career, when the sun was warmer and the oxygen content of the atmosphere was higher <g>, I had many debates with other programmers about how to make more robust & reliable code. Their opinion on faults was akin to just sweeping them under the rug, attempting to carry on, and hope things will be all right. My opinion was that the programs should be designed to exaggerate any existing bugs to force them out in the open, so they can be tracked down and fixed. The default NaN & NULL initializations fit right into that. If the hardware supported NaNs for integers, D would use that, too. The worst choice is C/C++'s, where any random garbage on the stack is used for the default initializer.
Jan 20 2003
prev sibling parent reply factory <tehdasX optushome.com.au> writes:
In article <b0c6pk$1n6b$1 digitaldaemon.com>, walter digitalmars.com 
says...
 
 "Ben Hinkle" <bhinkle mathworks.com> wrote in message
 news:b0c0n3$1jaj$1 digitaldaemon.com...
 Why is NaN the default value for floats and doubles? The most common
desired
 behavior is to default to 0. If the point of initializers is to make sure
 you specify an initial value in user code then NaN is fine because you
 almost never want to start a computation with NaN but if the point is to
 make a convenient default value then I'd suggest going with 0. It would
also
 improve ease-of-use because every language I can think of that has
defaults
 uses 0.
The reason is to cause the programmer to think about what the initial value should be. 0 is usually what is desired, but 1, pi, etc., are also candidates. Using NaN means that if you didn't specify one, and the result of the computation relies on it, the result would be NaN. If it were possible for NaNs for integers, I'd have used that too.
Hmm then why choose 0, which is a number which tends to hide and not cause much trouble, rather than something large that would screw up most calculations? - Factory
Jan 18 2003
parent reply "Walter" <walter digitalmars.com> writes:
"factory" <tehdasX optushome.com.au> wrote in message
news:MPG.189491406aa42260989681 news.digitalmars.com...
   Hmm then why choose 0, which is a number which tends to hide and not
 cause much trouble, rather than something large that would screw up most
 calculations?
You might be right, 0xDEADBEEF might be better <g>.
Jan 18 2003
parent factory <tehdasX optushome.com.au> writes:
In article <b0dh74$2dc3$2 digitaldaemon.com>, walter digitalmars.com 
says...
 
 "factory" <tehdasX optushome.com.au> wrote in message
 news:MPG.189491406aa42260989681 news.digitalmars.com...
   Hmm then why choose 0, which is a number which tends to hide and not
 cause much trouble, rather than something large that would screw up most
 calculations?
You might be right, 0xDEADBEEF might be better <g>.
Or 0xBAADF00D (which I found quite amusing at the time).. :) - Factory
Jan 20 2003
prev sibling next sibling parent reply "Sean L. Palmer" <seanpalmer directvinternet.com> writes:
Yes, yes, I agree;  it's been discussed to death already.  Walter seems
intent on forcing NaN's into our programs.

Sean

"Ben Hinkle" <bhinkle mathworks.com> wrote in message
news:b0c0n3$1jaj$1 digitaldaemon.com...
 Why is NaN the default value for floats and doubles? The most common
desired
 behavior is to default to 0. If the point of initializers is to make sure
 you specify an initial value in user code then NaN is fine because you
 almost never want to start a computation with NaN but if the point is to
 make a convenient default value then I'd suggest going with 0. It would
also
 improve ease-of-use because every language I can think of that has
defaults
 uses 0.

 just a thought,
 -Ben
Jan 18 2003
parent reply "Walter" <walter digitalmars.com> writes:
"Sean L. Palmer" <seanpalmer directvinternet.com> wrote in message
news:b0c8rq$1ofp$1 digitaldaemon.com...
 Yes, yes, I agree;  it's been discussed to death already.  Walter seems
 intent on forcing NaN's into our programs.
NaN's for the initializer are not that different from NULL for pointers - any use of a NULL pointer gets a GP fault, since NULL is guaranteed to not be a valid pointer. In D, you can also create your own typedefs and default initializers: typedef double mydouble = 0.0; mydouble m; // m is initialized to 0.0
Jan 18 2003
next sibling parent reply Norbert Nemec <Nobbi_at_theorie3.physik.uni-erlangen.de NOSPAM.COM> writes:
Walter wrote:
 NaN's for the initializer are not that different from NULL for pointers -
 any use of a NULL pointer gets a GP fault, since NULL is guaranteed to not
 be a valid pointer.
True, but why should floats be more similar to pointers than to integers? I guess, 0 is what most people would expect, and what would save the most unnecessary typing. (Actually, saving typing is about the only point of standard initializers. Otherwise, you could simply force explicit initializers to be used.) But then, NaN is not a bad choice either. It will be rather simple to find errors caused by it, and after killing their third bug of that kind, people will remember...
Jan 19 2003
parent "Walter" <walter digitalmars.com> writes:
"Norbert Nemec" <Nobbi_at_theorie3.physik.uni-erlangen.de NOSPAM.COM> wrote
in message news:b0dlq9$2fh5$1 digitaldaemon.com...
 Walter wrote:
 NaN's for the initializer are not that different from NULL for
pointers -
 any use of a NULL pointer gets a GP fault, since NULL is guaranteed to
not
 be a valid pointer.
True, but why should floats be more similar to pointers than to integers?
Unfortunately, there is no invalid bit pattern for integers. But there is for pointers and IEEE floats, so might as well make use of it.
 I
 guess, 0 is what most people would expect, and what would save the most
 unnecessary typing. (Actually, saving typing is about the only point of
 standard initializers. Otherwise, you could simply force explicit
 initializers to be used.)
The issue is more about minimizing the potential for bugs than saving typing.
 But then, NaN is not a bad choice either. It will be rather simple to find
 errors caused by it, and after killing their third bug of that kind,
people
 will remember...
I'd rather have a NaN show up in the result meaning I *know* there's a bug, than a result that is slightly wrong that slips by. NaNs have been around for 15 years or so, and few people use them. (Also, few C/C++ compilers ever bothered to support NaNs, meaning people who wanted to use them had to resort to ugly hacks.) NaNs rarely seem to be mentioned in numerical computing papers. I think they are a most overlooked tool. You could, of course, argue that they are overlooked for good reason that I am missing, but I think they are overlooked simply because people don't know what they're useful for.
Jan 19 2003
prev sibling parent "Sean L. Palmer" <seanpalmer directvinternet.com> writes:
"Walter" <walter digitalmars.com> wrote in message
news:b0dhu8$2dov$1 digitaldaemon.com...
 "Sean L. Palmer" <seanpalmer directvinternet.com> wrote in message
 news:b0c8rq$1ofp$1 digitaldaemon.com...
 Yes, yes, I agree;  it's been discussed to death already.  Walter seems
 intent on forcing NaN's into our programs.
NaN's for the initializer are not that different from NULL for pointers - any use of a NULL pointer gets a GP fault, since NULL is guaranteed to not be a valid pointer. In D, you can also create your own typedefs and default initializers: typedef double mydouble = 0.0; mydouble m; // m is initialized to 0.0
Didn't know that... that is a pretty cool feature! It's almost like a user-defined constructor for basic types. Syntax isn't unified with UDT's but it's still nice. Perhaps we could *change* the default initializer within a scope, such as a module or class? Without introducing a new type name? typedef double double = 0.0; typedef int int = 0; typedef char char = '\0'; You can always default-init int's to something wierd like 1 << (bits-1) == ~0u - (~0u>>1) == (0x80000000) which would be a sure sign that you forgot to initialize it. At least then D's initialization system would be unified. I'd rather have zeros, but having it unified to NaN or some reasonable garbage would be quite tolerable. I'd prefer just making it a compile time error if you don't initialize to something. If it's later assigned before the initialized value is used, the compiler can strip out the initialization. This 1 << (bits-1) makes a great garbage initializer BTW. It's equidistant from 0 in both directions, as far away from zero as possible. It's also potentially useful. It's tricky to compute if you don't a priori know the number of bits. It could possibly be used to figure out how many bits are there, and whether the type is signed or unsigned. Ok, so maybe not that useful. Not as useful as zero. But it seems your decision is not based on utility so much as on error trapping. There's precedent set by various heap managers to initialize memory to 0xcdcdcdcd, 0x55555555, 0xdeadbeef, or whatever. So long as it's large, easy to spot in a mem dump, odd, and not too close to zero, it'll work well to catch uninitialized variable bugs. Maybe 0x7fffffff would be better than 0x80000000 since it's odd. Sean
Jan 19 2003
prev sibling next sibling parent reply Mark Evans <Mark_member pathlink.com> writes:
Yes the default should always be zero.

M.
Jan 18 2003
parent reply Antti Sykari <jsykari gamma.hut.fi> writes:
Walter:
 I'd rather have a NaN show up in the result meaning I *know* there's
 a bug, than a result that is slightly wrong that slips by.
Mark Evans (and a lot of others):
 Yes the default should always be zero.
Seems that we're having a bit of a religious issue here ;) I'd vote for consistency. Either make unitialized variables all 0xDEADBEEF or similar -- or alternatively, initialize everything to zero. Less surprises, less exceptional cases to remember. I wouldn't know what to do myself, probably leave them unitialized in the release build and feed them some serious CAFEBABE in the debug build. By the way, what happens to variables of type 'char' now, if unitialized? Is anyone concerned about that? A. P.S. If someone has the time, resources and the knowledge of the right software, it would be really cool if there were a searchable web archive of this newsgroup's contents...
Jan 20 2003
parent "Walter" <walter digitalmars.com> writes:
"Antti Sykari" <jsykari gamma.hut.fi> wrote in message
news:86n0lvzhq6.fsf hoastest1-8c.hoasnet.inet.fi...
 By the way, what happens to variables of type 'char' now, if
 unitialized?
They are set to 0.
 Is anyone concerned about that?
I am.
 P.S. If someone has the time, resources and the knowledge of the right
 software, it would be really cool if there were a searchable web
 archive of this newsgroup's contents...
I agree - I've been unsuccessful trying to get google to scan it.
Jan 20 2003
prev sibling parent reply "Bjornar Svingen" <bjornar.svingen ktv.no> writes:
"Ben Hinkle" wrote
 Why is NaN the default value for floats and doubles? The most common
desired
 behavior is to default to 0. If the point of initializers is to make sure
 you specify an initial value in user code then NaN is fine because you
 almost never want to start a computation with NaN but if the point is to
 make a convenient default value then I'd suggest going with 0. It would
also
 improve ease-of-use because every language I can think of that has
defaults
 uses 0.
I don't know. Usually NaN tells you that some numerics is out of control, division by zero or some other divergent situation. By setting the default value to NaN you are initially "out of control" which is basicly what you are if you don't assign some value to it.
Jan 18 2003
parent reply "Walter" <walter digitalmars.com> writes:
"Bjornar Svingen" <bjornar.svingen ktv.no> wrote in message
news:b0cveo$2570$1 digitaldaemon.com...
 I don't know. Usually NaN tells you that some numerics is out of control,
 division by zero or some other divergent situation. By setting the default
 value to NaN you are initially "out of control" which is basicly what you
 are if you don't assign some value to it.
NaNs are also useful to fill in unknown values when crunching on real world data. If your result is a NaN, then you know that data is required to get a result. If your result is not NaN, then you know for sure that result doesn't depend on the unknown data.
Jan 18 2003
parent reply Burton Radons <loth users.sourceforge.net> writes:
Walter wrote:
 "Bjornar Svingen" <bjornar.svingen ktv.no> wrote in message
 news:b0cveo$2570$1 digitaldaemon.com...
 
I don't know. Usually NaN tells you that some numerics is out of control,
division by zero or some other divergent situation. By setting the default
value to NaN you are initially "out of control" which is basicly what you
are if you don't assign some value to it.
NaNs are also useful to fill in unknown values when crunching on real world data. If your result is a NaN, then you know that data is required to get a result. If your result is not NaN, then you know for sure that result doesn't depend on the unknown data.
My experience with it as a bug catch has been negative. Perhaps I'm just more careful than most, but the one time I've forgotten to put in the initializer, four months ago when coding some OpenGL stuff, the NaN was neither a help nor a hindrance. It was just an incorrect value that required the same amount of investigation as always to determine the source. I don't care what the default initialiser to float is, as 0 is only right about 20% of the time - then again, NaN is right only 1%. The default initialiser to int, however, is right about 70% of the time, which keeps locals blocks unpolluted.
Jan 20 2003
next sibling parent reply "Walter" <walter digitalmars.com> writes:
"Burton Radons" <loth users.sourceforge.net> wrote in message
news:3E2C6F6C.3080401 users.sourceforge.net...
 It was just an incorrect value that
 required the same amount of investigation as always to determine the
source. Yes, but with NaN you *know* that there's a bug in the code. With 0, your code can subtly produce the wrong results and the bug can go undetected. It's hard to overlook a NaN in your program's output! For example, I once read of a study where some calculators were reprogrammed to produce the wrong answers. Researchers wanted to know how wrong they could be before people using them (i.e. students) suspected something was wrong. Some never did, few noticed if the error was less than a factor of 2. But I'm sure they'd all notice something was amiss if the calculator flashed N-a-N in the display!
 I don't care what the default initialiser to float is, as 0 is only
 right about 20% of the time - then again, NaN is right only 1%.  The
 default initialiser to int, however, is right about 70% of the time,
 which keeps locals blocks unpolluted.
NaN would be even better if it was right 0% of the time. The idea is not to default it to the most probably useful value, but the value most likely to expose latent bugs. In design of critical systems, like the autopilot computer in an airplane, one of the big problems is determining if the autopilot computer is working right - if it isn't, it needs to be shut down. Being able to unambigously detect a failure is a big deal. A NaN result can provide that, a result off by 6% can't. An even better scheme would be if the hardware could be set to flag memory as uninitialized, so that a read on it would generate a gp fault. A write would work, and would clear that flag.
Jan 20 2003
parent reply "Mike Wynn" <mike.wynn l8night.co.uk> writes:
 An even better scheme would be if the hardware could be set to flag memory
 as uninitialized, so that a read on it would generate a gp fault. A write
 would work, and would clear that flag.
can't the compiler detect that a read occurs before the value is every written and issue a warning or error ? yes I know ... double func() { double d; int i = 10; while ( i > 3 ) { i--; if ( i == 8 ) { d =9.0; } } return d; } would produce a warning, because without actually evaluating the code it looks like there is a code path that can end up with d being undef at the return; (trivial example I know a bit of loop unwinding in the compiler would correctly detect that d is initialised in this code) but as you believe that default values should be right 0% of the time, why make sure all values are initialised, like Java lang does, even though the Java VM must init all values to 0, 0.0, '\0' or null; also I can't believe that you are not detecting reads that occur before writes, because it is very wasteful to generate code that always inits all the locals in the function prolog.
Jan 20 2003
parent reply "Walter" <walter digitalmars.com> writes:
"Mike Wynn" <mike.wynn l8night.co.uk> wrote in message
news:b0i1vf$1sqf$1 digitaldaemon.com...
 can't the compiler detect that a read occurs before the value is every
 written and issue a warning or error ?
Not 100%.
 yes I know ...

 double func() {
 double d;
 int i = 10;
 while ( i > 3 ) {
     i--;
     if ( i == 8 ) { d =9.0; }
 }
 return d;
 }

 would produce a warning, because without actually evaluating the code it
 looks like there is a code path that can end up with d being undef at the
 return; (trivial example I know a bit of loop unwinding in the compiler
 would correctly detect that d is initialised in this code)
Trivial or not, such examples do occur in real code. To get the compiler to not squawk about it, a spurious initialization to d is required. Being spurious, it serves merely to confuse anyone maintaining the code.
 but as you believe that default values should be right 0% of the time, why
 make sure all values are initialised, like Java lang does, even though the
 Java VM must init all values to 0, 0.0, '\0' or null;
Because if, as a programmer, you inadvertantly leave a path in where a result is used that is not initialized, you'll have a repeatable result rather than random garbage. Repeatability is an extremely valuable property when verifying code is correct, and when trying to track down a problem.
 also I can't believe that you are not detecting reads that occur before
 writes, because it is very wasteful to generate code that always inits all
 the locals in the function prolog.
Most default initializations wind up getting deleted by the optimizer, because it can detect most cases of redundant writes before any reads. Extra overhead from this D feature is practically nil.
Jan 20 2003
parent reply "Mike Wynn" <mike.wynn l8night.co.uk> writes:
 double func() {
 double d;
 int i = 10;
 while ( i > 3 ) {
     i--;
     if ( i == 8 ) { d =9.0; }
 }
 return d;
 }

 would produce a warning, because without actually evaluating the code it
 looks like there is a code path that can end up with d being undef at
the
 return; (trivial example I know a bit of loop unwinding in the compiler
 would correctly detect that d is initialised in this code)
Trivial or not, such examples do occur in real code. To get the compiler
to
 not squawk about it, a spurious initialization to d is required. Being
 spurious, it serves merely to confuse anyone maintaining the code.
I'm not sure I agree about maintanance, so there are some extra `x = 0;` 's thats nothing compared to the nightmare a few well designed macros can cause. I would prefer a language to force me to init a variable when it can not be 100% certain that I'm initing the value in the code before use, than a language that has default init value; there are lots of bugs you can introduce by incorrect init values; yours or default; but I am confused, you where saying that you would like code to GPF/seggy if you read from an uninited locations this is just a fail safe compile time version, I for one prefer compiler warning to GPF's, even over zealous one's on real world code not all code paths are executed during testing no matter how hard you try and test. a bit of compiler squawk compared to a day spent tracking GPF's or worse values that sometimes go wrong I know which I prefer. you could compile code into functions so that there is a bit map in the function frame (debug only) that is set on write and checked on read, thus have your exception/GPF/seggy/core dump when an uninitialize var is read.
 Most default initializations wind up getting deleted by the optimizer,
 because it can detect most cases of redundant writes before any reads.
Extra
 overhead from this D feature is practically nil.
so that also means unlike a c compiler where the init is not performed unless you put it there, D is always initing in the cases when a warning would be issued. so what it the harm in having to explicitly put on in (and if you do when a warning would not have been issued it will just optimise away) perhaps D needs pragmas, or perlish uses; for those who want compiler warnings (use one of, or somethiing like) use strict( initialize ); pragma warn( uninit ); // just warn pragma error( uninit ); // stop compiling that'll move the religious war out of the newgroup and into the office :) Mike.
Jan 20 2003
next sibling parent Mark Evans <Mark_member pathlink.com> writes:
The compiler can easily give warnings for variables used before initialization.
Personally I am tired of having to init every C number that I declare just
because C is too dumb.

Failure to init is a common programming error, but the compiler warning is good
enough.  Many is the time I've looked at code which reads,

int a,b,c,q,r,s
double x,y,z
a=0; b=0; c=0; q=0; r=0; s=0; x=0.0; y=0.0;

and said to myself "yep, everything is initialized in that function, so the bug
must be elsewhere..." Then three days later, I discover that I missed z=0.0.
It's easy to glance at init lists like this without careful reading and skip
past such bugs.  If I had a Real Language it would let me rely on certain
sensible defaults and not bother with trivia like this.

To me a compiler warning (that I can selectively shut off) is plenty good
enough.

Most array allocations want to start with the values zeroed out.  I just don't
buy that NaN's are good for anything.  If we want the compiler to lecture
programmers about good practice, instead of automating common tasks like zero
initialization, then crash the build if the code uses ANY uninitialized
variables.  A computation with a NaN involved with force him to go through
debugging procedures to find the source NaN.  Why not just crash the build right
at the source code line number and save him the trouble?

Mark
Jan 20 2003
prev sibling parent "Walter" <walter digitalmars.com> writes:
"Mike Wynn" <mike.wynn l8night.co.uk> wrote in message
news:b0iq0p$28id$1 digitaldaemon.com...
 I'm not sure I agree about maintanance, so there are some extra `x = 0;`
's Making maintainable code means that there is a reason for everything in it, there is nothing extra or superfluous. Having to add in dead assignments to placate the compiler is a bug in the language design.
 I would prefer a language to force me to init a variable when it can not
be
 100% certain that I'm initing the value in the code before use, than a
 language that has default init value;
 there are lots of bugs you can introduce by incorrect init values; yours
or
 default;
 but I am confused, you where saying that you would like code to GPF/seggy
if
 you read from an uninited locations
 this is just a fail safe compile time version, I for one prefer compiler
 warning to GPF's, even over zealous one's
 on real world code not all code paths are executed during testing no
matter
 how hard you try and test.
 a bit of compiler squawk compared to a day spent tracking GPF's or worse
 values that sometimes go wrong I know which I prefer.
GPF's are much maligned, but they are a fabulous improvement over real mode DOS, where when programs went awry they scrambled your hard disk. The philosophy here is that if there is a bug in the program, the program gives a clear indication of it and (if possible) halts. That is far, far better than undetected bugs that result in subtly wrong answers.
 you could compile code into functions so that there is a bit map in the
 function frame (debug only) that is set on write  and checked on read,
thus
 have your exception/GPF/seggy/core dump when an uninitialize var is read.
That's possible, but it would be remarkably slow <g>.
 Most default initializations wind up getting deleted by the optimizer,
 because it can detect most cases of redundant writes before any reads.
Extra
 overhead from this D feature is practically nil.
so that also means unlike a c compiler where the init is not performed unless you put it there, D is always initing in the cases when a warning would be issued. so what it the harm in having to explicitly put on in
(and
 if you do when a warning would not have been issued it will just optimise
 away)
The harm is in the maintenance mode when one wonders why that dead assignment is there. There's further harm in that how dead assigments are detected is inexact, and varies from technique to technique - you'd have a program declared valid by one D compiler and rejected by another. D shouldn't be specifying exactly how advanced data flow analysis is to be implemented.
 perhaps D needs pragmas, or perlish uses;

 for those who want compiler warnings (use one of, or somethiing like)
 use strict( initialize );
 pragma warn( uninit ); // just warn
 pragma error( uninit ); // stop compiling

 that'll move the religious war out of the newgroup and into the office :)
I really, really want to avoid things like that.
Jan 21 2003
prev sibling parent reply "Roberto Mariottini" <rmariottini lycosmail.com> writes:
"Burton Radons" <loth users.sourceforge.net> ha scritto nel messaggio
news:3E2C6F6C.3080401 users.sourceforge.net...

[...]
 My experience with it as a bug catch has been negative.  Perhaps I'm
 just more careful than most, but the one time I've forgotten to put in
 the initializer, four months ago when coding some OpenGL stuff, the NaN
 was neither a help nor a hindrance.  It was just an incorrect value that
 required the same amount of investigation as always to determine the
source. That's because NaNs _propagate_ instead of _killing_ like null pointer faults. Is there a way to set the CPU to throw an exception in case of NaN arithmetic operation? This would "catch the bug at the first debug"(TM). Ciao
Jan 24 2003
parent "Walter" <walter digitalmars.com> writes:
"Roberto Mariottini" <rmariottini lycosmail.com> wrote in message
news:b0qt2r$pi4$1 digitaldaemon.com...
 Is there a way to set the CPU to throw an exception in case of NaN
 arithmetic operation?
 This would "catch the bug at the first debug"(TM).
Yes, but that wouldn't be part of the official D semantics because NaNs do have legitimate uses in computation.
Jan 24 2003