1

Here is an example below where I try to assign a const pointer to a const pointer in the struct and the compiler won't let me. But I can assign a literal without any problem. I've also tried this case with out any const's and with some const's if you know what I mean, but I still don't see why the compiler is cool with the literals but as issues with the char* in the assignment.

const char* cat_surname = "Snack";

typedef struct
{
    const char* first;
    const char* last;
}PET_T;

PET_T dog =
{
        "Rover",    // OK
        "Cateater"  // OK
};

PET_T cat =
{
        "Tasty",    // OK
        cat_surname // ERROR :-(
};

I get this compiler error:

error: initializer element is not constant

Using Arch Linux gcc version 4.8.2 20140206 (prerelease) (GCC)

gjcamann
  • 621
  • 4
  • 14
  • 1
    `const`-qualified objects are not compile-time constants. – effeffe Apr 15 '14 at 17:48
  • 2
    possible duplicate of [Error "initializer element is not constant" when trying to initialize variable with const](http://stackoverflow.com/questions/3025050/error-initializer-element-is-not-constant-when-trying-to-initialize-variable-w) – effeffe Apr 15 '14 at 17:56
  • 1
    Suggest `const char cat_surname[] = "Snack"; PET_T cat = { "Tasty", cat_surname };` – chux - Reinstate Monica Apr 15 '14 at 18:06
  • you should probably post that as an answer @chux... the rationale is that the addresses of file-scope objects count as constants; so `cat_surname` here decays to `&cat_surname[0]` which the linker is able to fill in. – M.M Apr 15 '14 at 21:25
  • I don't know of any logical reason why the standard says that `const`-qualified variables shouldn't be able to have their value used as initializer later on – M.M Apr 15 '14 at 21:27
  • 1
    @chux thanks, this worked! On a side note I accidentally clicked the up arrow twice(upvote/downvote) and now it won't let me upvote it for good. Sorry about that, but thanks for the help. – gjcamann Apr 17 '14 at 21:03

1 Answers1

2

To avoid the problem, make cat_surname an array of const char rather than a pointer to const char.

const char cat_surname[] = "Snack"; 
PET_T cat = {
  "Tasty",
  cat_surname
};

Note: The use of const does not mean that the object is constant. It's a bit more like "read-only". Below, i may have different values as foo() is called, but the function foo may not change it.

void foo(const int i) {
  i = 5; // compile time error
}

The use of const in const char* cat_surname = "Snack"; does not imply cat_surname can not change value. const here means that the data cat_surname points to should not be attempted to be change as follows:

*cat_surname = 'X'; // bad

The compiler error "initializer element is not constant" wants a true constant. An array is that: the array's first element is always at the same address.

@Matt McNabb brings up a good point that the initial value of cat.last could be cat_surname. I do not have a strong reason why C does not allow that.

chux - Reinstate Monica
  • 143,097
  • 13
  • 135
  • 256