Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C: Assigning "static const char * const" to "static const char *"

I have a program with some global strings defined at the top of the file like this:

static const char * const STRING_A = "STRING A";
static const char * const STRING_B = "STRING B";

Then in the main program loop I repeatedly call a function. This function contains a pointer which is to point to the above strings, depending on user input. By default I want it to be set to STRING_A, so what I essentially have is this:

// Called repeatedly from a loop.
void input_function()
{
    static const char *current = STRING_A;

    // Do stuff and reassign different strings to "current"
    ...
}

The problem that I have is that when compiling I get "error: initializer element is not constant". This is using GCC 4.7.2. What confuses me more is that the error goes away if I get rid of the "static" keyword in the input function. This isn't a solution though, as the static keyword is needed for the function to keep track of the current string between calls.

Obviously I could fix this in many ways, most simply by just getting rid of some of the const qualifiers. But I want to understand why this isn't working.

My current understanding is that the global string variables can't be modified to point to different strings, and neither can their individual characters be modified. The static keyword keeps them local to the source file.

For the current variable in my function my understanding is that the static keyword allows it to retain its value over multiple calls to the function, and that the const qualifier in this case means that the string pointed to by current can change - but not the characters of the string which it points to.

I'm not seeing any conflicts in those statements, so I don't understand why the compiler gives an error - particularly why it doesn't have a problem if current's "static" specifier is removed.

Thanks if someone can explain what the problem is here.

like image 953
Adam Goodwin Avatar asked Aug 10 '13 15:08

Adam Goodwin


People also ask

What is the difference between const char * and char * const?

The difference is that const char * is a pointer to a const char , while char * const is a constant pointer to a char . The first, the value being pointed to can't be changed but the pointer can be. The second, the value being pointed at can change but the pointer can't (similar to a reference).

Can const char * be reassigned?

Variables defined with const cannot be Reassigned.

What is const char * const *?

const char* const says that the pointer can point to a constant char and value of int pointed by this pointer cannot be changed. And we cannot change the value of pointer as well it is now constant and it cannot point to another constant char.

What is a static const char * in C++?

const char* is a pointer to a constant char, meaning the char in question can't be modified. char* const is a constant pointer to a char, meaning the char can be modified, but the pointer can not (e.g. you can't make it point somewhere else).


2 Answers

6.7.8/4 [C99]:

All the expressions in an initializer for an object that has static storage duration shall be constant expressions or string literals.

STRING_A is neither, hence the error.

One to way to work around this would be along the following lines:

void input_function()
{
    static const char *current = NULL;
    if (current == NULL) {
        current = STRING_A;
    }

    ...
}
like image 110
NPE Avatar answered Oct 19 '22 01:10

NPE


It's because STRING_A is not a compile-time constant. Your interpretations are right however you cannot initialize a constant to be a non-constant value (such as STRING_A).

How does the compiler know what STRING_A points at while it is compiling? It doesn't -- STRING_A will point to different addresses in the read-only section of memory on each execution of program, dependant on where the string literal is in memory.

You would need to do the following to work around this restraint while pertaining the same effect:

// Defines current to be a null pointer.
static const char *current = NULL;

// Determine if current is a null pointer.
if ( current == NULL ) current = STRING_A;
like image 3
Jacob Pollack Avatar answered Oct 18 '22 23:10

Jacob Pollack