Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Internal static array (K&R month_name() function)

Tags:

c

In K&R section 5.8, there is a function month_name() which uses an internal static char pointer array, and makes a point to mention that this is an "ideal application for an internal static array." The function is below:

/* month_name: return name of n-th month */
char *month_name(int n)
{
    static char *name[] = {
        "Illegal month",
        "January", "February", "March",
        "April", "May", "June",
        "July", "August", "September",
        "October", "November", "December"
    };
    return (n < 1 || n > 12) ? name[0] : name[n];
}

My understanding is that static when applied to internal variable means that the variable hangs around after function returns, and still exists for the next time the function is entered. So the only theory I could come up for why static is used here, is that maybe if static wasn't used, the char *name[] would be re-initialized every single time the function was entered, which would be inefficient. I did try the function with the static keyword removed, and it still seemed to work fine. So I wanted to test my theory that maybe the array was being created more than once. I created this test, which may be totally worthless, but it's the best I could come up with:

int main(void)
{
    printf("%s\n", month_name(1)); // print string
    printf("%d\n", month_name(1)); // print address of string
    printf("%s\n", month_name(1)); // print string
    printf("%d\n", month_name(1)); // print address of string
}

My theory was that if the string array was being duplicated inefficiently, the address would change for the second function call... but it remained the same. So I even went a step further and tried to initialize another character array just to shift the allocation a bit (again, this may be totally worthless based on my limited knowledge of how allocation works):

int main(void)
{
    printf("%s\n", month_name(1)); // print string
    printf("%d\n", month_name(1)); // print address of string
    char dummy[] = "dummy";
    printf("%s\n", month_name(1)); // print string
    printf("%d\n", month_name(1)); // print address of string
}

But, the address of "January" is still the same for both function calls, even with the char *name[] in the month_name function NOT being declared as static.

So... couple questions.

1) What is the point of it being static? Why is it an ideal application for internal static array?

2) Is there any merit to the logic behind my test above?

Thanks!

like image 213
The111 Avatar asked May 05 '26 06:05

The111


1 Answers

If it's not static it's on the stack. Since the function is returning a char * pointer to it, that's kind of important and it needs to be done that way.

If it's not static, outside of the function you have a pointer to a stack variable that is no longer valid. Your "test" isn't showing this because the memory hasn't yet been reused. Make no mistake - it will be at some point.

Edit: Jim brings up a good point in the comments below that I didn't think about initially. Since these are string literals, they are already in read-only memory. I think that using static here simply keeps from re-initializing the char *name[] array each time. The initial answer above does apply to other data types, but in this case I don't think it does.

like image 138
Brian Roach Avatar answered May 06 '26 20:05

Brian Roach



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!