문제

I just had Apple's C/C++ compiler initialize a float to a non-zero value (approx "-0.1").

That was a big surprise - and only happened occasionally (but 100% repeatably, if you ran through the same function calls / args beforehand). It took a long time to track down (using assertions).

I'd thought floats were zero-initialized. Googling suggests that I was thinking of C++ (which of course is much more precise about this stuff - c.f. SO: What are primitive types default-initialized to in C++? ).

But maybe Apple's excuse here is that their compiler was running in C mode ... so: what about C? What should happen, and (more importantly) what's typical?

(OF COURSE I should have initialized it manually - I normally do - but in this one case I failed. I didn't expect it to blow up, though!)

(Google is proving worse than useless for any discussion of this - their current search refuses to show "C" without "C++". Keeps deciding I'm too stupid, and ignoring even my input even when running in advanced mode)


Here's the actual source example where it happened. At first I thought there might be a problem with definitions of MAX and ABS (maybe MAX(ABS,ABS) doesnt always do what you'd expect?) ... but digging with assertions and debugger, I eventually found it was the missing initialization - that float was getting init'd to non-zero value VERY occasionally):

float crossedVectorX = ... // generates a float
float crossedVectorY = ... // generates a float

float infitesimal; // no manual init
float smallPositiveFloat = 2.0 / MAX( ABS(crossedVectorX), ABS(crossedVectorY));

// NB: confirmed with debugger + assertions that smallPositiveFloat was always positive

infitesimal += smallPositiveFloat;

NSAssert( infitesimal >= 0.0, @"This is sometimes NOT TRUE" );
도움이 되었습니까?

해결책

Only objects with static storage duration are initialized to 0 if there is no explicit initializer.

#include <stdio.h>

float f;         // initialized to 0, file scope variables have static storage
static float g;  // initialized to 0

int main(void)
{
    float h;  // not initialized to 0, automatic storage duration
    static float i;  // initialized to 0

    return 0;
}

Objects with automatic storage duration (like h in the example above) that are not explicitly initialized have an indeterminate value. Reading their value is undefined behavior.

EDIT: for the sake of completeness, since C11 objects with thread storage duration are also initialized to 0 if there is no explicit initializer.

다른 팁

The relevant part of the standard is §6.7.9 paragraph 10:

If an object that has automatic storage duration is not initialized explicitly, its value is indeterminate.

If your variable had thread or static storage duration instead, then the next part of the paragraph would take effect:

If an object that has static or thread storage duration is not initialized explicitly, then:

-- if it has pointer type, it is initialized to a null pointer;

-- if it has arithmetic type, it is initialized to (positive or unsigned) zero;

...

I would also note that you should turn on your compiler's warnings (specifically the warning for uninitialized variables), as that should have identified the problem for you immediately.

Static variable would be initialized to zero, but I'm guessing you are talking about a local variable (i.e. stack, or automatic) - these are not initialized for you, but get whatever value is at that memory on the stack.

I had to pull out my K&R for this answer:

In the absence of explicit initialization, external and static variables are guaranteed to be initialized to zero; automatic and register variables have undefined (i.e., garbage) initial values.

I don't believe that any of the standards for C define initial values for variables in general. This would be in accord with the general philosophy of and application domain for C -- programming for grown-ups who may, one day, have reason to want their compiler to not initialise a variable for them and who know that it is their responsibility to initialise their own variables.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top