January 20, 2003 Re: NaN initializers for floating point? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Robert M. Münch | "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. |
January 20, 2003 Re: NaN initializers for floating point? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Mark Evans | 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... |
January 20, 2003 Re: NaN initializers for floating point? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Walter |
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.
|
January 20, 2003 Re: NaN initializers for floating point? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Burton Radons | "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. |
January 20, 2003 Re: NaN initializers for floating point? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Walter | > 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.
|
January 21, 2003 Re: NaN initializers for floating point? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Antti Sykari | "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. |
January 21, 2003 Re: NaN initializers for floating point? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Mike Wynn | "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. |
January 21, 2003 Re: NaN initializers for floating point? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Walter | > > > > 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. |
January 21, 2003 Re: NaN initializers for floating point? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Mike Wynn | 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 |
January 21, 2003 Re: NaN initializers for floating point? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Mike Wynn | "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. |
Copyright © 1999-2021 by the D Language Foundation