int nan

Nick Sabalausky a at a.a
Sun Jun 28 14:31:40 PDT 2009


"Michiel Helvensteijn" <m.helvensteijn.remove at gmail.com> wrote in message 
news:h28i61$1hl3$1 at digitalmars.com...
> Nick Sabalausky wrote:
>
>> The fix would be one of the following, depending on what the code is
>> actually doing:
>>
>> ---------------
>> // Instead of knee-jerking i to 0, we default init it to
>> // whatever safe value we want it to be if the loop
>> // doesn't set it. This, of course, may or may not
>> // be zero, depending on the code, but regardless,
>> // there are times when this IS perfectly safe.
>>
>> int i = contextDependentInitVal;
>> for(int j = foo(); j > 3; j--) i = j;
>> auto k = i;
>> ---------------
>>
>> ---------------
>> int i;
>> bool isSet = false; // making i nullable would be better
>> for(int j = foo(); j > 3; j--) {
>>     i = j;
>>     isSet = true;
>> }
>> if(isSet) {
>>     auto k = i;
>> } else { /* handle the problem */ }
>> ---------------
>
> Keep in mind that we're talking about a situation in which we're sure 'i'
> will always be set. If this is not so, the program is incorrect, and we
> would want to see one error or another. Your first solution would be
> misleading in that case. Any initial value you choose would be a hack to
> silence the compiler.

It's a situation where we're *initially* sure 'i' will always be set. But 
once we see that error from the compiler, we have to reassess that belief. 
There are three possibilities when that happens:

1. It will always be set because of the function's contract. In this case, 
we do the formal contract stuff I advocated earlier. And we can certainly 
come up with ways to be minimally-verbose with this for trivial cases. So 
this case gets eliminated.

2. It will always be set, but *only* because of the function's 
implementation. This *should* cause a compiler error, because if it's 
allowed by the function's formal contract, then that very fact means that we 
*should* assume that this may very well flip-flop anytime that either foo or 
anything foo may rely upon is changed.

3. We were, in fact, *mistaken* in thinking that what we were doing would 
always leave 'i' inited (this does happen). This causes the programmer to 
reassess their approach. Depending on what they're trying to do, the 
solution might involve rewriting a loop that's basically fubared already, or 
in some cases it may very well be as simple as adding a default init value 
(this does happen).

> A variation on your second solution then:
>
> int i;
> bool isSet = false; // making i nullable would be better
> for(int j = foo(); j > 3; j--) {
>    i = j;
>    isSet = true;
> }
> assert(isSet);
> auto k = i;
>
> This is the basic solution I would always choose in the absence of the
> grail. As you say, ideally, the 'uninitialized' state should be part
> of 'i', not a separate variable. Reading 'i' would then automatically
> assert its initialization at runtime.

Yea, that works too. It's effectively a sub-case of my "if(isSet) else {/* 
handle this somehow*/ }", and more-or-less what I had in mind.

>
> I guess that brings us back to one of those scenario's I mentioned in
> another subthread. As compilers become more sophisticated, they will be
> able to remove the explicit initialization, the test and the extended 
> state
> in more complex situations.
>

Agreed, but with the caveat that care should be taken to ensure these new 
rules don't allow non-localized flip-flopping when something's[1] 
implementation is changed, because then the programmer has to start 
remembering and analyzing an increasingly complex set of rules.

[1] Side-trip to spell-check land again: Apparently OpenOffice doesn't think 
"something" can be made possessive. (But then again, maybe it technically 
can't in super-anal-grammar-police land, not like I would know ;) )

>> Also, keep in mind that while, under this mechanism, it is certainly
>> possible for a coder to cause bugs by always knee-jerking the value to
>> zero whenever the compiler complains, that's also a possibility under the
>> "holy grail" approach.
>
> That's true. But if we did have the grail, the compiler would also be able
> to see that knee-jerking 'i' would not satisfy the contract of the outer
> function.
>

No, it wouldn't, because it would have no way of knowing that's a knee-jerk 
fix for a "using uninited var" error. But maybe I misunderstand you?





More information about the Digitalmars-d mailing list