473,748 Members | 7,571 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

assigning string constant to char *

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
10 9465
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
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
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

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

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
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
zeppe <ze***@nospam.r emove.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
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
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

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

5
7429
by: Anton Pervukhin | last post by:
Hello! Imagine the situation you have a class that interprets the command line of the program you are executing. This class is written by third party and has a main function parse with arguments the same as main: ClassA::parse(char **argv, int argc) While trying to write test cases for this function I came across the warnings appeared when I tried to initialize 'char** argv' straightly
3
11190
by: Senthilraja | last post by:
I am able to compile the following code and get "hello" as ouput everytime I execute it:- #include <stdio.h> int main (void) { char *str; str="hello"; puts(str); return 0;
4
5393
by: songkv | last post by:
Hi, I am trying to reassign an array of char to a string literal by calling a function. In the function I use pointer-to-pointer since I want to reassign the "string array pointer" to the string literal. But the second printf seems to give me garbage. Any advise on what I am doing wrong? Thanx
6
7609
by: karthi | last post by:
hi, I need user defined function that converts string to float in c. since the library function atof and strtod occupies large space in my processor memory I can't use it in my code. regards, Karthi
1
1575
by: Arun | last post by:
Hi all, The code below gives compilation error (in gcc). "initializer element is not constant" @line 11 1 #include <stdio.h> 2 char* ptr="string"; 3 //char ptr="string"; 4 5 typedef struct 6 {
14
1859
by: nospam | last post by:
From the book "There is an important difference between these definitions: char amessage="now is the time"; char *pmessage ="now is the time"; snip On the other hand, pmessage is a pointer, initialized to point a string const; the pointer may be modified to point elsewhere, but the
4
3894
by: allan.mcrae | last post by:
As part of a very simple memory leak detector, I am trying to store the value of __FILE__ in a char*. Since gcc4.2 I get the following warning... warning: deprecated conversion from string constant to 'char*' object. The macro of delete assigns this to a global char* which is used to track where deletions were made. Something like: #define delete delete_FILE_ = __FILE__, \
20
691
by: karthikbalaguru | last post by:
Hi, String constant being modifiable in C++ but, not modifiable in C. that is, In C++, the following example output will be "Mplusplus" char *str1 = "Cplusplus"; *str1 = 'M'; In C, the above example will produce an error as we are trying to modify a constant. So, str1 is not a string constant in C++.
13
21848
by: sinbad | last post by:
hi, how to concatenate a "hash defined" constant value to another "hash defined" constant string. For example #define ABC 100 #define MYSTR "The value of ABC is" Now i need a string that will concatenate the value of ABC to MYSTR . I need this at compile time.
0
8991
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
9372
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
1
9324
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
9247
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
1
6796
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
4606
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
1
3313
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
2
2783
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
3
2215
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.