简体   繁体   中英

Assigned value is garbage or undefined logic error in XCode

I am updating our iPhone app to iOs4 and I ran into an issue "Pass-by-argument in function call is undefined" in the code

for (i = 0; i < self.numberOfSegments; i++) {
        [self setWidth:round(width[i]) forSegmentAtIndex:i];
}

Which is fair enough, width[i] hasn't been initialized. Updating the code (below) however gives me this new error, "Assigned value is garbage or undefined". Reading up on this I think that segWidth retains its value as garbage - is that correct and if so how do I clear it?

for (i = 0; i < self.numberOfSegments; i++) {
    float segWidth = (float)width[i];
    [self setWidth:round(segWidth) forSegmentAtIndex:i];
}

------------- EDIT ------------------

Thanks for the replies guys. More information as follows;

A genericised version of the method is shown below as someFunction. I have removed the ugly cast but still see the "Assigned Value is Garbage or undefined" logic error for the line segWidth = width[i];

I agree it appears the value width[i] doesn't have clear initialisation, I am unsure if it's my lack of understanding of basic Obj-c float types or if there is a logic flaw in my assignment syntax?

- (void)someFunction
{
    unsigned int n = self.numberOfSegments;
    float width[n];

    for (i = 0; i < n; i++) {
       width[i] = someFloatValue;
    }

    ...    

    for (i = 0; i < self.numberOfSegments; i++) {
       float segWidth = 0.0;
       segWidth = width[i];

       [self setWidth:round(segWidth) forSegmentAtIndex:i];
    }

}

Definition of setWidth is:

- (void)setWidth:(CGFloat)width forSegmentAtIndex:(NSUInteger)segment;         // set to 0.0 width to autosize. default is 0.0

I'm assuming that you are calling:

- (void)setWidth:(CGFloat)width forSegmentAtIndex:(NSUInteger)segment

And that Pass-by-argument in function call is undefined is actually the LLVM static analyzer error when you do Build and Analyze. (Both rather important data points -- passing along exactly what you were doing and exactly what the output was is quite helpful).

And you say that width[i] hasn't been initialized.

Your fix of adding float segWidth = (float)width[i] very much should cause the analyzer to complain with ** Assigned value is garbage or undefined**. You haven't actually set width[i] to anything. I would suggest filing a bug against the static analyzer, though, because that first error message is really quite thoroughly obtuse.

As Joshua also said, that cast is really weird, too. In general, in Objective-C you should very rarely have to use type casting and pretty much never use it on scalar types.


Consider the two loop counts:

for (i = 0; i < n; i++) {
...
}


for (i = 0; i < self.numberOfSegments; i++) {
...
}

The static analyzer doesn't know that n == self.numberOfSegments and, thus, must assume that the second loop could loop longer than the first. Now, you might say, "But I assigned n = self.numberOfSegments above?!"

You did, but that value could have changed between the first call and second call and, thus, the analyzer has correctly identified that you might be using an uninitialized value.

(Really, it should be saying that you might run off the end of the array, because that is the real risk).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM