Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

"Initializer element is not a compile-time constant" why?

I have this code:

- (NSString *) calculate: (uint) position {
    static NSArray * localArray = [NSArray arrayWithArray: self.container.objects ];
    // some un related code
    return obj;
}

The compiler complains saying: "Initializer element is not a compile-time constant". It happened when I added "static" to localArray. But why?

like image 973
subzero Avatar asked Sep 06 '12 16:09

subzero


People also ask

Is a compile-time constant?

A compile-time constant is a value that is computed at the compilation-time. Whereas, A runtime constant is a value that is computed only at the time when the program is running. 2. A compile-time constant will have the same value each time when the source code is run.

What is compile-time variable?

4.1. Compile-Time Constants. A Java variable is a compile-time constant if it's of a primitive type or String, declared final, initialized within its declaration, and with a constant expression. Strings are a special case on top of the primitive types because they are immutable and live in a String pool.


2 Answers

Because [NSArray arrayWithArray: self.container.objects ] isn't a compile-time constant, it's an expression that must be evaluated at runtime. In C and Objective-C, static variables inside functions must be initialized with compile-time constants, whereas C++ and Objective-C++ are more lenient and allow non-compile-time constants.

Either compile your code as Objective-C++, or refactor it into something like this:

static NSArray *localArray = nil;
if (localArray == nil)
    localArray = [NSArray arrayWithArray: self.container.objects ];

Which is fairly similar to the code that the compiler would generate under the hood for a static variable initialized with a non-compile-time constant anyways (in actuality, it would use a second global flag indicating if the value was initialized, rather than using a sentinel value like nil here; in this case, we are assuming that localArray will never be nil). You can check out your compiler's disassembly for that if you want.

like image 128
Adam Rosenfield Avatar answered Sep 19 '22 08:09

Adam Rosenfield


You just can't initialize a static variable with a non-static value that will be known/modified at runtime.

You should probably do something like this:

static NSArray *localArray = nil;
localArray = ...;

The first instruction will be executed once in your app lifecycle. The second instruction will be executed every time the calculate: method is called.

Nevertheless, pay attention to the fact that using static variables can lead to buggy behaviors if not done properly so if you feel uneasy with these, you should probably not use them.

like image 24
Dirty Henry Avatar answered Sep 21 '22 08:09

Dirty Henry