[M3devel] warning for uninitialized variables?
Jay K
jay.krell at cornell.edu
Fri Jun 4 01:59:01 CEST 2010
> The NORETURN type would have no values
Everyone else seems to do with pragma-ish things.
I don't know what is best.
Visual C++ has __declspec(noreturn).
gcc has __attribute__((noreturn)) or somesuch. Maybe it is named something else.
Visual C++ puts a breakpoint instruction after any call to a noreturn function.
abort() for example is noreturn.
>> I'm also nervous about us not taking a hard line on integer overflow.
> I agree. But I do need a way to turn it off for specific operations so
> Perhaps also a specific type for wrap-around arithmetic?
Yes. Or a new module.
And I believe a bunch more is needed in general.
Signed and unsigned.
And overflow should do one:
return an "error" code (boolean? true for success? or true for overflow? Booleans can be so ambiguous..)
raise an exception
silently wraparound
I have to look into Modula-3 generics.
Ideally this can be implemented with generics and not actually writing all N combinations.
And without any "runtime switching".
For example, the generic parameters would be
"Word"
"Error"
Word would look like Word.
Except all the functions would probably return BOOLEAN to indicate overflow.
Even if that isn't the actual "error code".
Error would expose type T that the actual implementation would return.
Oh, wait, no, Modula-3 can't do that -- there is no "VOID" type.
So..instead.. decide what the "error code" form is -- probably returning FALSE.
The Error module would expose one function, OnError.
The main code when it recieves false from "Word" would call Error.OnError.
There'd be two Error's versions. In one, OnError would do nothing. In the other, it would raise an exception.
Hm.
If Modula-3 didn't have this pesky "eval" thing, you'd be done.
Silent wraparound would be calling the "OnError donothing" form, but you'd just ignore the error.
This is unfortunate I think.
Btw, C++ folks eventually realized you need to be able to write code like this:
PROCEDURE F1();
PROCEDURE F2() =
BEGIN
RETURN F1();
END F1;
for reasons related to templates/generics.
You need to be able to return the result of a function you call, without knowing the return type, and the return type possibly being void. The need for this feature is obvious once you spend a few days using templates/generics.
Anyway, for silent overflow you'd have to layer over the bool version, just prepending eval.
Something like that.
The lowest level implementation probably returns bool.
The Error module could also expose a type ErrorType and some constants like OverflowError and NoError.
Maybe I'll code this up soon in pure Modula-3.
Where/who/when are the interface police?
We can add stuff to m3core or libm3 at will? As long as don't extend or change stuff in the green book?
- Jay
----------------------------------------
> Date: Thu, 3 Jun 2010 19:30:22 -0400
> From: hendrik at topoi.pooq.com
> To: m3devel at elegosoft.com
> Subject: Re: [M3devel] warning for uninitialized variables?
>
> On Wed, Jun 02, 2010 at 04:50:28AM +0000, Jay K wrote:
>>
>> Wow. You really surprise me Mika.
>>
>>
>> To warn on this kind of thing, to me, there is no question.
>>
>>
>> Limting the affects by virtue of being safe isn't much consolation.
>> The program can easily go down a "safe" but very incorrect path.
>>
>>
>> There are several forms.
>> In fact, sometimes the compiler says something "is" used uninitialized.
>> Sometimes it says "maybe".
>>
>>
>> In your example, generally, once the address is taken of a variable,
>> the compiler gives up. Esp. if that address is passed to a function it doesn't "see".
>>
>>
>> However compilers are getting better.
>> Windows headers are now annotated with "in" and "out", etc. with
>> a calculus behind them, not just informal human definitions.
>>
>>
>> So if you pass something by pointer to "in" you should a warning/error.
>> If it is "out", ok.
>>
>>
>> The annotations can even be checked, if you write to something that is "in"
>> you should get a warning/error.
>>
>>
>> There are many more warnings in the tree than I have yet looked at.
>> I've seen a few forms.
>> Some are because the compiler doesn't know that some functions don't return.
>> I'll see about improving that. Though I think there's a limit to how good I can manage,
>> unless we add a <* noreturn *> pragma.
>
> Or a new type that has *no* values at all, and therefore can never be
> returned by anything. If it'e the type of an expression, that
> expression can never return a value.
>
> Notice, that if you were to let statements have a type (Algol 68 does,
> calling it the VOID type) that type would *not* be the type with no
> values at all. The VOID type has one value, and needs log(1) = 0 bits
> to store it.
>
> The NORETURN type would have no values, is never stored. log(0) doesn't
> give a meaningful numper of bits, which is right.
>
>>
>> I grant that by initializing to 0, I haven't necessarily made the code correct either.
>> But at least it is now consistent.
>
> It's very useful for code execution to ne repeatable.
>
>>
>>
>> Even better would be runtime checks that stop if a variable is read
>> before written.
>
> Takes extra storage, unless there are bit patterns that are known to fit
> in the available space *and* be invalid values for the type.
>
>>
>>
>> Uninitialized values can be different run to run.
>> Repeatability and consistency are important.
>
> *VERY*
>
>> I'm also nervous about us not taking a hard line on integer overflow.
>> Overflown math doesn't necessarily lead to array out of bounds soon or ever.
>> It too can lead to incorrect but safe behavior.
>
> I agree. But I do need a way to turn it off for specific operations so
> I get modulo results. Perhaps also a specific type for wrap-around
> arithmetic?
>
> -- hendrik
>
More information about the M3devel
mailing list