Confused about static modifier with pointer


#1

For the BNRLogger program, the lastTimeString method is as follows:

[code]

  • (NSString *)lastTimeString
    {
    static NSDateFormatter *dateFormatter = nil;

    if (!dateFormatter)
    {
    dateFormatter = [[NSDateFormatter alloc] init];
    [dateFormatter setTimeStyle:NSDateFormatterMediumStyle];
    [dateFormatter setDateStyle:NSDateFormatterMediumStyle];
    NSLog(@“created dateFormatter”);

    }
    return [dateFormatter stringFromDate:self.lastTime];
    }[/code]

When the code in the first part of this chapter is run, the dateFormatter pointer is created and, I assume because it is set to nil, the if (!dateFormatter) statement evaluates to true, and the code within the if statement is executed. This method gets called every two seconds. From the second call of this method, onward, the if (!dateFormatter) statement evaluates to false, and the code within the if statement does not get executed. But, why is that? Immediately before the if statement, the method declares the dateFormatter pointer to be nil again. Shouldn’t the if statement once again evaluate as true?


#2

[quote][code]- (NSString *)lastTimeString
{
static NSDateFormatter *dateFormatter = nil;

if (!dateFormatter)
{
    dateFormatter = [[NSDateFormatter alloc] init];
    ...        
}
return [dateFormatter stringFromDate:self.lastTime];

}[/code][/quote]
To explain what’s going on here with respect to the static dateFormatter variable, one needs to invoke the language (C, C++, Objective-C) rule concerning the initialization of static variables.

The rule says: A static variable, whether declared inside a function or outside, is initialized only once with the value provided on the declaration line.

Since, on the declaration line, the static variable dateFormatter is initialized to nil (this is done even before the function is invoked), when the function is called the variable is not set to nil again contrary to what one might expect.

[Become a competent programmer: pretty-function.org]


#3

This makes sense now, thank you very much.


#4

excellent, I came here looking for the same answer - thank you!


#5

Dear ibex,

Thanks for your always comprehensive replies.
On this issue i’m not satisfied with your answer. On below code i change static value many times and initialize value does not remain;

void test(){
static int x = 0;
x = 87;
x= 88;
x++;
printf("%d\n",x);
}
int main(...){
test();
test();
test();
test();
}

It returns:
89
89
89
89


#6

[quote]…On below code i change static value many times and initialize value does not remain;

void test(){
   static int x = 0;
   x = 87;
   x= 88;
   x++;
   printf("%d\n",x);
}
int main(...){
   test();
   test();
   test();
   test();
}

It returns:
89
89
89
89[/quote]
That’s because of another rule: If you assign a value to a variable, the variable will lose its current value:

void Foo ()
{
   // create bar with initial value 200
   static long bar = 200;
    // Here, the current value of bar is either 200 or 203.
    // Note: we can't say it is 200 because bar is a static variable,
    // and this function may have been called once already.

    bar = 203;  
    // The current value of bar is now 203
}

Because bar is a static variable declared inside a function, if it were possible to see the value of bar from outside after invoking the function Foo (), you would see the value of bar equal to 203.

To understand the static-initialisation rule, rewrite your original code like this:

void test(){
    static int x = 0;
     x++;
     printf ("%d\n",x);
}
int main(...){
     test();
     test();
     test();
     test();
}

Now you will get this output:

1
2
3
4

because x is initialised only once and its value is kept after the function test () returns.


#7

Thanks ibex,

Got it :wink: