By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
434,795 Members | 1,251 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 434,795 IT Pros & Developers. It's quick & easy.

assigning string constant to char *

P: n/a
The first of the following functions compiles, the second gives what
I think is a spurious error:

"cannot convert `const char[5]' to `char *' in assignment".

void foo(int m) {
char *str;
if (m < 4) str = "%01x";
else if (m < 9) str = "%02x";
else str = "%03x";
}

void foo(int m) {
char *str;
str = m < 4 ? "%01x" : m < 9 ? "%02x" : "%03x";
}

Any idea why gcc doesn't like the second version? If I compile
it as a C file instead of C++, it works fine.

Steve
Aug 25 '06 #1
Share this Question
Share on Google+
10 Replies


P: n/a
Steve Pope wrote:
The first of the following functions compiles, the second gives what
I think is a spurious error:

"cannot convert `const char[5]' to `char *' in assignment".

void foo(int m) {
char *str;
if (m < 4) str = "%01x";
else if (m < 9) str = "%02x";
else str = "%03x";
}

void foo(int m) {
char *str;
str = m < 4 ? "%01x" : m < 9 ? "%02x" : "%03x";
}

Any idea why gcc doesn't like the second version? If I compile
it as a C file instead of C++, it works fine.
It is not a spurious error, just an obscure one. A string constant
(like "%01x") is actually of type const char[5], which decays to const
char*. For historical reasons (so as not to break a lot of existing
code), you can assign a string constant to a non-const char*, although
it bends (if not breaks) const-correctness. In the first example, you
are assigning a string constant to a char*, and that's permitted. In
the second example, you are assigning not a string constant, but an
expression instead, to the char*. That's not permitted - the exception
to const-correctness is intentionally kept narrow.

To solve your problem change your second example to the following:

void foo(int m) {
const char *str = m < 4 ? "%01x" : m < 9 ? "%02x" : "%03x";
}

Since you're now assigning to a const char*, not to a non-const char*,
the problem disappears.

Best regards,

Tom

Aug 25 '06 #2

P: n/a
Thomas Tutone <Th***********@yahoo.comwrote:
>Steve Pope wrote:
>void foo(int m) {
char *str;
str = m < 4 ? "%01x" : m < 9 ? "%02x" : "%03x";
}
>Any idea why gcc doesn't like the second version? If I compile
it as a C file instead of C++, it works fine.
>It is not a spurious error, just an obscure one. A string constant
(like "%01x") is actually of type const char[5], which decays to const
char*. For historical reasons (so as not to break a lot of existing
code), you can assign a string constant to a non-const char*, although
it bends (if not breaks) const-correctness. In the first example, you
are assigning a string constant to a char*, and that's permitted. In
the second example, you are assigning not a string constant, but an
expression instead, to the char*. That's not permitted - the exception
to const-correctness is intentionally kept narrow.
Okay, that makes sense.
>To solve your problem change your second example to the following:
>void foo(int m) {
const char *str = m < 4 ? "%01x" : m < 9 ? "%02x" : "%03x";
}
>Since you're now assigning to a const char*, not to a non-const char*,
the problem disappears.
That works, but oddly so does the following:

const char *str;
str = m < 4 ? "%01x" : m < 9 ? "%02x" : "%03x";
if (m 12) str = "%04x";

It seems the "const" does not mean as much for type char * as
it does for other types.

Steve
>
Best regards,

Tom

Aug 25 '06 #3

P: n/a
Steve Pope wrote:
It seems the "const" does not mean as much for type char * as
it does for other types.
It's an issue related not to the char type, but to the string literals:
the following conversion are allowed:
string literal -const char*
string literal -char* // deprecated, but valid

but, of course, it's not valid
const char* -char*

so, you can convert string literal to char* only directly, not through
const char* (as you tried with the conditional operator '?').

Bye,

Zeppe
Aug 25 '06 #4

P: n/a

Steve Pope skrev:

[snip]
>
Okay, that makes sense.
To solve your problem change your second example to the following:
void foo(int m) {
const char *str = m < 4 ? "%01x" : m < 9 ? "%02x" : "%03x";
}
Since you're now assigning to a const char*, not to a non-const char*,
the problem disappears.

That works, but oddly so does the following:

const char *str;
str = m < 4 ? "%01x" : m < 9 ? "%02x" : "%03x";
if (m 12) str = "%04x";

It seems the "const" does not mean as much for type char * as
it does for other types.
Well no.... as Thomas Tutone explained, you can break constness for
char only. But what surprises you above is that you can reassign str.
This is because you read the type wrongly. const char *str means that
str is a pointer to a constant char. The pointer is by itself not
constant - you can assign it to anything you want (and actually you
should be surprised by both assignments above). If you wanted the
pointer to be constant, the notation would have to be char * const str
(and then you better remember to initialise it!). This way the content
of *str would be changeable.

/Peter
>
Steve

Best regards,

Tom
Aug 25 '06 #5

P: n/a

Steve Pope wrote:
Thomas Tutone <Th***********@yahoo.comwrote:
[snip]
It is not a spurious error, just an obscure one. A string constant
(like "%01x") is actually of type const char[5], which decays to const
char*. For historical reasons (so as not to break a lot of existing
code), you can assign a string constant to a non-const char*, although
it bends (if not breaks) const-correctness. In the first example, you
are assigning a string constant to a char*, and that's permitted. In
the second example, you are assigning not a string constant, but an
expression instead, to the char*. That's not permitted - the exception
to const-correctness is intentionally kept narrow.

Okay, that makes sense.
To solve your problem change your second example to the following:
void foo(int m) {
const char *str = m < 4 ? "%01x" : m < 9 ? "%02x" : "%03x";
}
Since you're now assigning to a const char*, not to a non-const char*,
the problem disappears.

That works, but oddly so does the following:

const char *str;
str = m < 4 ? "%01x" : m < 9 ? "%02x" : "%03x";
if (m 12) str = "%04x";

It seems the "const" does not mean as much for type char * as
it does for other types.
Sorry, my changing your example so that the str was initialized upon
creation confused matters. A const char* means "a pointer to a char
that is const," not "a const pointer to a char." The latter would be
char* const. You can reassign a const char*, you just can't change the
contents of what it points to.

Best regards,

Tom

Aug 25 '06 #6

P: n/a
Steve Pope wrote:
Thomas Tutone <Th***********@yahoo.comwrote:
[..]
>To solve your problem change your second example to the following:
>void foo(int m) {
const char *str = m < 4 ? "%01x" : m < 9 ? "%02x" : "%03x";
}
>Since you're now assigning to a const char*, not to a non-const
char*, the problem disappears.

That works, but oddly so does the following:

const char *str;
str = m < 4 ? "%01x" : m < 9 ? "%02x" : "%03x";
if (m 12) str = "%04x";

It seems the "const" does not mean as much for type char * as
it does for other types.
You confuse your consts. In

const char * str;

'const' relates to the char, not to the char*. You need to read up on
declaration syntax and its meaning.

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Aug 25 '06 #7

P: n/a
zeppe <ze***@nospam.remove.all.this.email.itwrote:
>Steve Pope wrote:
>It seems the "const" does not mean as much for type char * as
it does for other types.
It's an issue related not to the char type, but to the string
literals: the following conversion are allowed:
string literal -const char*
string literal -char* // deprecated, but valid

but, of course, it's not valid
const char* -char*

so, you can convert string literal to char* only directly, not through
const char* (as you tried with the conditional operator '?').
Seems that *is* related to the type char *, since the following
code also compiles, whereas analogous code with str of any type
other than char * does not compile. To me it looks like gcc
at least has special-cased "const char *" to not actually be const.

char a[10], b[10];

void foo(int m) {
const char *str;
str = a;
if (m 12) str = b;
}

Cheers,
Steve
Aug 25 '06 #8

P: n/a
Steve Pope wrote:
[..] To me it looks like gcc
at least has special-cased "const char *" to not actually be const.

char a[10], b[10];

void foo(int m) {
const char *str;
str = a;
if (m 12) str = b;
}
There you go again... 'str' is a non-const pointer to const char.
You can assign new value to it from an array (which when used in
an exrpession like assignment above decays to a pointer to char).

If you want 'str' to be non-changeable pointer, you need to declare
*it itself* const:

char * const str;

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Aug 25 '06 #9

P: n/a
Steve Pope wrote:
>but, of course, it's not valid
const char* -char*
Seems that *is* related to the type char *, since the following
code also compiles, whereas analogous code with str of any type
other than char * does not compile. To me it looks like gcc
at least has special-cased "const char *" to not actually be const.

char a[10], b[10];

void foo(int m) {
const char *str;
str = a;
if (m 12) str = b;
}
Actually, this is the opposite cast, i.e.:
char* -const char*

that of course is correct (and the above code works also with int*,
double* and any other pointer).
BTW, it seems that we are talking about two different things: I was
explaining the strange behaviour due to the conversion from literal to
char*, and you are referring to the fact that is seems possible o change
value to a const variable (that is, as others explained, is not const,
but it's const the value the pointer is referring to).
Bye,

Zeppe
Aug 25 '06 #10

P: n/a
peter koch <pe***************@gmail.comwrote:
>But what surprises you above is that you can reassign str.
This is because you read the type wrongly. const char *str means that
str is a pointer to a constant char. The pointer is by itself not
constant - you can assign it to anything you want (and actually you
should be surprised by both assignments above). If you wanted the
pointer to be constant, the notation would have to be char * const str
(and then you better remember to initialise it!).
Thanks, that does explain my confusion here.

Steve
Aug 25 '06 #11

This discussion thread is closed

Replies have been disabled for this discussion.