Search code examples
cternary-operatorstring-literals

Ternary operation with a string output in C


Can someone explain why this simple ternary operation won't even compile, in C?

void main(int argc, char *argv[]){
    int a = atoi(argv[1]);
    char foo[] = (a == 1) ? "bar1" : "bar2";
}

It seems to be a problem with strings in particular.


Solution

  • A string literal "bar", when used in an expression (in this case, inside the ternary operator), is a pointer to pre-allocated memory. You cannot initialize an array using a pointer to data, only using a literal ("..." or {...}).

    Instead, you could assign it to a char *:

    const char *foo = (a == 1) ? "bar1" : "bar2";
    

    This will not make a copy of the literal but point to it, so you should not modify the elements of foo. If you need a copy, you can use memcpy, provided that you know how big to declare the array:

    char foo[5];
    memcpy(foo, (a == 1) ? "bar1" : "bar2", sizeof foo);
    

    If you particularly want to be able to assign the contents, then there is a trick to doing that; it is possible to implicitly copy the contents of a struct using assignment (as well as returning it from a function, and so on), no matter what the struct contains, and you could put a character array in a struct:

    typedef struct { 
      char contents[5];
    } mystring;
    
    mystring foo = (a == 1) ? (mystring){"bar1"} : (mystring){"bar2"};
    // You can also use assignments.
    foo = (mystring){"baz"};
    

    Just like the second option, when you do this you have to pick a fixed size for the array in the struct declaration. If you have strings of unbounded length, then you must use pointers.