tags:

views:

157

answers:

4

var1 must hold a string whether it is empty or not or my program will segfault. But gcc complains that the empty string literal is constant while var1 is not. The following is an example of what I am talking about.

How can I fix this ?

warning: assignment discards qualifiers from pointer target type

char *var1 = NULL;
if(var1 == NULL)
{
    var1 = malloc(strlen(var2) + 1);
    strcpy(var1, var2);
}else{
    var1 = ""; // warning points here
}

EDIT:

String literals are not modifiable so I use this flag to warn me:

-Wwrite-strings

A: 

Declare var1 as constant:

const char *var1 = NULL;

The const there means you won't change the contents of the thing pointed to (so, eg, you won't try to change the contents of the string literal). You're still free to change what the variable points to.

Tommy
OP wants to use `var1` as first parameter to `strcpy()`. If `var1` is `const char*` then OP wouldn't do that.
Donotalo
Good point; it'd allow the literal assignment but not the subsequent memcpy. So the poster would need to change the second to copy var2 somewhere, then assign that pointer to var1 — effectively like creating a mutable quantity then flagging it as immutable.
Tommy
+2  A: 

To assign a empty string, do something like this:

var1 = malloc(1); /* 1 byte */
var1[0] = '\0';
Matias Valdenegro
Or: `var1 = strdup("")`
sth
+2  A: 

A string literal is of type char[]. When used in most contexts, a string literal (of type char[]) decays to a pointer to its first element (it becomes type char*).

If your compiler complains about assigning a value of type char* (your "") to an object of type char* (your var1), your compiler is broken.

Or, most likely, you are not invoking it as a 'C' compiler, but as a compiler of a language similar to C but not quite C.

Try: gcc -Wno-write-strings ... to disable that specific gcc extension :-)


Edit

A string literal is an array of characters (of type char[]), but it is not modifiable. For historic (or some other peculiar) reasons they are not of type const char[] as a "unmodifiable character array" looks like it should be.

With the "-Wwrite-strings" compiler option, gcc tries to be helpful and changes its definition of string literals.

If you want to be safe and have your string literals be of type const char[], just remember you're no longer compiling C (C89, C90, C99, whatever) and be happy. As other answers said: declare your pointers as const or copy the unmodifiable characters to modifiable objects.

pmg
A: 

String literals have type const char* (or maybe const char[]) in recent versions of C. It is unsafe to assign a string literal to a char* because modifying that char* results in undefined behaviour, reflected in their const type.

DeadMG
Hm, where did you read this about the `const`? My copy of C99 says that the elements of a string literal are `char`.
Jens Gustedt
@Jens Gustedt: The individual elements of a string literal are char. That doesn't mean that pointing to them is not const. Think about it- string literals are immutable, so since the language offers a pointer-to-immutable type, that would offer far superior correctness, which they do. The only reason char* x = "lol" is allowed is for backwards compability.
DeadMG
@DeadMG: I can "think" of them as I want, and I never would have the idea to change such a thing, believe me. Please, just don't put wrong things in your answer. And saying that pointing to an array will necessarily have the `const` attribute, is well, just plain wrong. The type of string literals is `char[]` and nothing else, it is defined as that. Whether or not this is historical is another thing, and that there is an explicit mention that changing them will result in undefined behavior is yet another thing. A correct answer would contain all that.
Jens Gustedt
@Jens: I'm pretty damn sure that in recent versions of C, string literals have type const char* or const char[]. I never said nor implied that pointing to arrays implies const - it's only for string literals.
DeadMG
@DeadMG: Quote from the C99 standard: On the other hand, the declaration`char *p = "abc";`defines p with type ‘‘pointer to char’’ and initializes it to point to an object with type ‘‘array of char’’with length 4 whose elements are initialized with a character string literal. If an attempt is made to use p tomodify the contents of the array, the behavior is undefined.
Jens Gustedt
@Jens: Yes, I know. Hence, I said that it's legal in C to assign a string literal to a non-const char pointer, even though it's a const type.
DeadMG