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

pointer to const string

P: n/a
Hi all,
I'm a beginner and my question is:
Are there any differences between
char *p = "Hello, world!";
and
const char *p = "Hello, world!";
?

Dec 2 '06 #1
Share this Question
Share on Google+
41 Replies


P: n/a
// more information
If I define p & p_const in a function as follows:
char *p = "Hello, world!";
const char *p_const = "Hello, world!";
It seems that a TI's compiler doesn't allow
p_const[0] = 'A';
but it allows
p[0] = 'A';
And MSVC6.0 doesn't allow both of them.
What about the C standard?

Thanks for any advice!

Dec 2 '06 #2

P: n/a
On 1 Dec 2006 23:54:56 -0800, "Dead Loop" <fo************@gmail.com>
wrote:
>// more information
If I define p & p_const in a function as follows:
char *p = "Hello, world!";
const char *p_const = "Hello, world!";
It seems that a TI's compiler doesn't allow
p_const[0] = 'A';
but it allows
p[0] = 'A';
And MSVC6.0 doesn't allow both of them.
What about the C standard?
http://www.c-faq.com/ansi/strlitnotconst.html

comp.lang.c FAQ list Question 11.8b
Q: If you can't modify string literals, why aren't they defined as
being arrays of const characters?

A: One reason is that so very much code contains lines like

char *p = "Hello, world!";

which are not necessarily incorrect. These lines would suffer the
diagnostic messages, but it's really any later attempt to modify what
p points to which would be problems.

See also question 1.32.

--
jay

Dec 2 '06 #3

P: n/a
Dead Loop wrote:
// more information
If I define p & p_const in a function as follows:
char *p = "Hello, world!";
const char *p_const = "Hello, world!";
It seems that a TI's compiler doesn't allow
p_const[0] = 'A';
but it allows
p[0] = 'A';
And MSVC6.0 doesn't allow both of them.
What about the C standard?
Modifying string literals leads to undefined behaviour.

Dec 2 '06 #4

P: n/a
MQ

Dead Loop wrote:
Hi all,
I'm a beginner and my question is:
Are there any differences between
char *p = "Hello, world!";
and
const char *p = "Hello, world!";
?
You shouldn't modify string literals, as it leads to undefined
behaviour. I believe on Windows platforms, string literals are kept in
a read-only data segment. Some systems may put them in a read/write
data segment

Dec 2 '06 #5

P: n/a
Dead Loop said:
// more information
If I define p & p_const in a function as follows:
char *p = "Hello, world!";
const char *p_const = "Hello, world!";
It seems that a TI's compiler doesn't allow
p_const[0] = 'A';
but it allows
p[0] = 'A';
And MSVC6.0 doesn't allow both of them.
What about the C standard?
The C Standard says, in effect, "don't do that", but doesn't actually
prevent you from doing it. It's like a sign next to a broken bridge:
"Bridge Out - Turn Around And Go Back While There Is Still Time!". If you
want to try to cross it anyway, that's your problem, not the sign's
problem. MSVC is within its rights to prevent modification of a string
literal, and TI is within its rights to allow it. The Standard only says
that, if you try, the behaviour of the program is undefined. So any
behaviour is allowed, including allowing it (TI), disallowing it (MSVC),
and launching an Exocet missile at a passing cruiser (which is how the
Falklands War really started).

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at the above domain, - www.
Dec 2 '06 #6

P: n/a

"Dead Loop д
"
// more information
If I define p & p_const in a function as follows:
char *p = "Hello, world!";
const char *p_const = "Hello, world!";
It seems that a TI's compiler doesn't allow
p_const[0] = 'A';
but it allows
p[0] = 'A';
And MSVC6.0 doesn't allow both of them.
What about the C standard?

Thanks for any advice!
I just write a simple c program to test this.

Code snippets as follows:
char *p = "Hello, world!";
const char *p_const = "Hello, world!";
//p_const[0] = 'A'; // Error: assignment of read-only location
p[0] = 'A';

Both gcc(in dev-c++) and msvc6 can compile right. But both run ERROR.
This means that memory can not be written, that is, "You shouldn't
modify string literals".
besides,
when I debug it in dev-c++ and msvc6, I find that both p & p_const
point to the same address.

Dec 2 '06 #7

P: n/a
Allen said:

<snip>
I just write a simple c program to test this.

Code snippets as follows:
char *p = "Hello, world!";
const char *p_const = "Hello, world!";
//p_const[0] = 'A'; // Error: assignment of read-only location
p[0] = 'A';

Both gcc(in dev-c++) and msvc6 can compile right. But both run ERROR.
This means that memory can not be written, that is, "You shouldn't
modify string literals".
The reverse, however, is not the case. Had your experiment not uncovered a
run-time error, that would not have implied that the code was correct C.

Experimentation gives empirical results, not proofs (but, as you have
discovered, it can certainly provide counter-examples).

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at the above domain, - www.
Dec 2 '06 #8

P: n/a
Richard Heathfield wrote:
Dead Loop said:
// more information
If I define p & p_const in a function as follows:
char *p = "Hello, world!";
const char *p_const = "Hello, world!";
It seems that a TI's compiler doesn't allow
p_const[0] = 'A';
but it allows
p[0] = 'A';
And MSVC6.0 doesn't allow both of them.
What about the C standard?

The C Standard says, in effect, "don't do that", but doesn't actually
prevent you from doing it. [...]
MSVC is within its rights to prevent modification of a string
literal, [...]
Can MSVC be a conforming compiler by preventing modification of string
literals?

Dec 2 '06 #9

P: n/a
santosh said:
Richard Heathfield wrote:
>Dead Loop said:
// more information
If I define p & p_const in a function as follows:
char *p = "Hello, world!";
const char *p_const = "Hello, world!";
It seems that a TI's compiler doesn't allow
p_const[0] = 'A';
but it allows
p[0] = 'A';
And MSVC6.0 doesn't allow both of them.
What about the C standard?

The C Standard says, in effect, "don't do that", but doesn't actually
prevent you from doing it. [...]
MSVC is within its rights to prevent modification of a string
literal, [...]

Can MSVC be a conforming compiler by preventing modification of string
literals?
Sure. If you try to do it, the behaviour is undefined, so all bets are off.
Implementations can do what they like, and that certainly includes
preventing the modification.

Some implementations put string literals into read-only memory. That might
be "logically" read-only, in the sense that the implementation simply
enforces a "you can look but you'd better not touch" policy, or it might
even be physically read-only, in the sense that the hardware for updating
the memory is simply not present.

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at the above domain, - www.
Dec 2 '06 #10

P: n/a
Richard Heathfield wrote:
Dead Loop said:
>// more information
If I define p & p_const in a function as follows:
char *p = "Hello, world!";
const char *p_const = "Hello, world!";
It seems that a TI's compiler doesn't allow
p_const[0] = 'A';
but it allows
p[0] = 'A';
And MSVC6.0 doesn't allow both of them.
What about the C standard?

The C Standard says, in effect, "don't do that", but doesn't actually
prevent you from doing it. It's like a sign next to a broken bridge:
"Bridge Out - Turn Around And Go Back While There Is Still Time!". If you
want to try to cross it anyway, that's your problem, not the sign's
problem. MSVC is within its rights to prevent modification of a string
literal, and TI is within its rights to allow it. The Standard only says
that, if you try, the behaviour of the program is undefined. So any
behaviour is allowed, including allowing it (TI), disallowing it (MSVC),
and launching an Exocet missile at a passing cruiser (which is how the
Falklands War really started).
I didn't realize that the DeathStar 9000 was available then. Was
this remarkable foresight by Maggie? Circa 1982, I believe, and
predating the C standard.

--
Chuck F (cbfalconer at maineline dot net)
Available for consulting/temporary embedded and systems.
<http://cbfalconer.home.att.net>
Dec 2 '06 #11

P: n/a
CBFalconer wrote:
I didn't realize that the DeathStar 9000 was available then.
"DeathStation" !!!

It's a computer, not a satellite.

"I ran it on my DeathStation 9000 and demons flew out of my nose"
12 Aug 1998 15:51:08 -0700, k...@cafe.net (Kaz Kylheku)

--
pete
Dec 2 '06 #12

P: n/a

"Richard Heathfield д
"
Allen said:

<snip>
I just write a simple c program to test this.

Code snippets as follows:
char *p = "Hello, world!";
const char *p_const = "Hello, world!";
//p_const[0] = 'A'; // Error: assignment of read-only location
p[0] = 'A';

Both gcc(in dev-c++) and msvc6 can compile right. But both run ERROR.
This means that memory can not be written, that is, "You shouldn't
modify string literals".

The reverse, however, is not the case. Had your experiment not uncovered a
run-time error, that would not have implied that the code was correct C.

Experimentation gives empirical results, not proofs (but, as you have
discovered, it can certainly provide counter-examples).

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at the above domain, - www.
I agree with you.

But,
I post that thread just want to show that Dead Loop made a mistake in
his question.
>It seems that a TI's compiler doesn't allow
p_const[0] = 'A';
but it allows
p[0] = 'A';
And MSVC6.0 doesn't allow both of them.
There is a mistake.
p_const[0] = 'A'; // this is a compile error
p[0] = 'A'; // this is run-time error
we konw that, these are different types of error. But if we say
compiler "allow" xxx , I think, it means there isn't any compile error.

p.s. English is not my mather language. Maybe I didn't say it clearly :(

Dec 2 '06 #13

P: n/a
Richard Heathfield <rj*@see.sig.invalidwrites:
santosh said:
>Richard Heathfield wrote:
>>Dead Loop said:

// more information
If I define p & p_const in a function as follows:
char *p = "Hello, world!";
const char *p_const = "Hello, world!";
It seems that a TI's compiler doesn't allow
p_const[0] = 'A';
but it allows
p[0] = 'A';
And MSVC6.0 doesn't allow both of them.
What about the C standard?

The C Standard says, in effect, "don't do that", but doesn't actually
prevent you from doing it. [...]
MSVC is within its rights to prevent modification of a string
literal, [...]

Can MSVC be a conforming compiler by preventing modification of string
literals?

Sure. If you try to do it, the behaviour is undefined, so all bets are off.
Implementations can do what they like, and that certainly includes
preventing the modification.
On the other hand, actually treating string literals as "const" is
potentially non-conforming. gcc, for example, does this with
"-Wwrite-strings", but that by itself doesn't make gcc non-conforming;
it merely causes it to issue some (misleading) warning messages.

For example, this program:

#include <stdio.h>
int main(void)
{
char *s = "hello, world";
puts(s);
return 0;
}

is strictly conforming (modulo any questions about the success or
failure of writing to stdout). But if string literals really were
const, then assigning the address of one to a non-const char* would be
a constraint violation. gcc with "-Wwrite-strings" warns:

c.c:4: warning: initialization discards qualifiers from pointer target type

But the program still compiles and executes, and an implementation can
issue any extraneous diagnostics it likes.

With "-Wwrite-strings -Werror", gcc rejects this program, and is
therefore non-conforming.

Assigning the address of a string literal to a non-const char* creates
the *potential* for attempting to modify the literal. A conforming
compiler is not allowed to reject the program based on that potential.
But if the program actually attempted to modify the string literal:

char *s = "hello, world";
s[0] = 'h';

that would invoke undefined behavior, and one valid consequence of
that is rejecting the program during compilation.

Enclosing the assignment in "if (0) { ... }" raises some interesting
questions, but I've already strayed enough from what the OP was
actually asking.

Hmm. I wonder if MSVC6.0 was being invoked as a C++ compiler. I
think C++ has different rules about string literals than C does.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <* <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Dec 2 '06 #14

P: n/a
pete <pf*****@mindspring.comwrites:
CBFalconer wrote:
>I didn't realize that the DeathStar 9000 was available then.

"DeathStation" !!!

It's a computer, not a satellite.

"I ran it on my DeathStation 9000 and demons flew out of my nose"
12 Aug 1998 15:51:08 -0700, k...@cafe.net (Kaz Kylheku)
The DeathStation 9000 was invented in 1998. Shortly thereafter,
somebody executed a program on it that included the statement
"i = i++;"; this caused a fully operational DS9K to appear in 1982.
That machine is believed to be responsible for a number of other
unpleasant historical events (see Chicxulub), but that, of course, is
off-topic.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <* <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Dec 2 '06 #15

P: n/a
Keith Thompson wrote:
Richard Heathfield <rj*@see.sig.invalidwrites:
>>santosh said:
>>>
Can MSVC be a conforming compiler by preventing modification of string
literals?

Sure. If you try to do it, the behaviour is undefined, so all bets are off.
Implementations can do what they like, and that certainly includes
preventing the modification.

On the other hand, actually treating string literals as "const" is
potentially non-conforming. gcc, for example, does this with
"-Wwrite-strings", but that by itself doesn't make gcc non-conforming;
it merely causes it to issue some (misleading) warning messages.

For example, this program:

#include <stdio.h>
int main(void)
{
char *s = "hello, world";
puts(s);
return 0;
}

is strictly conforming (modulo any questions about the success or
failure of writing to stdout). But if string literals really were
const, then assigning the address of one to a non-const char* would be
a constraint violation.
Another case where the C++ committee made the right call and the C
committee missed an opportunity.

--
Ian Collins.
Dec 2 '06 #16

P: n/a
Ian Collins <ia******@hotmail.comwrites:
Keith Thompson wrote:
>Richard Heathfield <rj*@see.sig.invalidwrites:
>>>santosh said:
Can MSVC be a conforming compiler by preventing modification of string
literals?

Sure. If you try to do it, the behaviour is undefined, so all bets are off.
Implementations can do what they like, and that certainly includes
preventing the modification.

On the other hand, actually treating string literals as "const" is
potentially non-conforming. gcc, for example, does this with
"-Wwrite-strings", but that by itself doesn't make gcc non-conforming;
it merely causes it to issue some (misleading) warning messages.

For example, this program:

#include <stdio.h>
int main(void)
{
char *s = "hello, world";
puts(s);
return 0;
}

is strictly conforming (modulo any questions about the success or
failure of writing to stdout). But if string literals really were
const, then assigning the address of one to a non-const char* would be
a constraint violation.
Another case where the C++ committee made the right call and the C
committee missed an opportunity.
But the C committee had a good reason to make the call it made.
Making string literals const would have broken every single pre-ANSI
program that passed a string literal as an argument to a function
outside the standard library. Pre-ANSI C didn't have the "const"
keyword, so it wasn't possible to declare a parameter of type "const
char*". (I exclude the standard library because it can be updated
with "const" keywords along with the rest of the implementation.)

C++, being a new language, was not as constrained by backward
compatibility.

It *might* have been worthwhile to make the change in C99, but it
still would have broken existing code and likely slowed adoption even
more.

(I think C++ is a bit lax about const-correctness in some cases, but I
don't remember the (off-topic) details.)

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <* <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Dec 2 '06 #17

P: n/a
Keith Thompson wrote:
Ian Collins <ia******@hotmail.comwrites:
>>Keith Thompson wrote:
>>>
is strictly conforming (modulo any questions about the success or
failure of writing to stdout). But if string literals really were
const, then assigning the address of one to a non-const char* would be
a constraint violation.

Another case where the C++ committee made the right call and the C
committee missed an opportunity.

But the C committee had a good reason to make the call it made.
Making string literals const would have broken every single pre-ANSI
program that passed a string literal as an argument to a function
outside the standard library. Pre-ANSI C didn't have the "const"
keyword, so it wasn't possible to declare a parameter of type "const
char*". (I exclude the standard library because it can be updated
with "const" keywords along with the rest of the implementation.)

C++, being a new language, was not as constrained by backward
compatibility.
It was to the extent that there was plenty of pre-standard code in use.
The benefits of the change where judged to outweigh the cost. I still
think C should have gone the same way. At least it would reduce the
traffic here!

Like any language change, compiler writers are free to add backwards
compatibility options.

--
Ian Collins.
Dec 2 '06 #18

P: n/a
"Allen Said
"
I post that thread just want to show that Dead Loop made a mistake in
his question.
It seems that a TI's compiler doesn't allow
p_const[0] = 'A';
but it allows
p[0] = 'A';
And MSVC6.0 doesn't allow both of them.
There is a mistake.
p_const[0] = 'A'; // this is a compile error
p[0] = 'A'; // this is run-time error
we konw that, these are different types of error. But if we say
compiler "allow" xxx , I think, it means there isn't any compile error.

p.s. English is not my mather language. Maybe I didn't say it clearly :(
Hi Allen,
I really didn't describe it clearly. Thanks for your help! ^_^

Dec 3 '06 #19

P: n/a
Hi all,
thanks for your help!
I understand that
1) I cannot modify the string by ^pointer p^ because it points to a
literal string.
2) I cannot modify the string by ^pointer p_const^ because first it is
(const char *) type and second it points to a literal string.
Am I right?

Dec 3 '06 #20

P: n/a
Dead Loop wrote:
>
I understand that
1) I cannot modify the string by ^pointer p^ because it points to a
literal string.
2) I cannot modify the string by ^pointer p_const^ because first it is
(const char *) type and second it points to a literal string.
Am I right?
Who knows? You didn't quote anything. What is ^pointer p^
supposed to represent? I see no literal string. I see nothing of
type (const char *).

--
Chuck F (cbfalconer at maineline dot net)
Available for consulting/temporary embedded and systems.
<http://cbfalconer.home.att.net>
Dec 3 '06 #21

P: n/a
On 1 Dec 2006 23:54:56 -0800, "Dead Loop" <fo************@gmail.com>
wrote:
>// more information
If I define p & p_const in a function as follows:
char *p = "Hello, world!";
const char *p_const = "Hello, world!";
It seems that a TI's compiler doesn't allow
p_const[0] = 'A';
but it allows
p[0] = 'A';
And MSVC6.0 doesn't allow both of them.
What about the C standard?
The C standard distinguishes between violations of the language (for
which the compiler is required to issue a diagnostic and which are
often referred to as compile-time errors) and valid language
constructs which lead to undefined behavior (for which a diagnostic is
not required and which are referred to as run-time errors). Some
compilers make the extra effort to detect undefined behavior and issue
a diagnostic. Some compilers go even further and attempt to identify
"unsafe" code and issue a diagnostic. Neither of these last two are
required by the standard.

Any attempt to modify a char by dereferencing p_const is a language
violation that requires a diagnostic.

Attempts to modify a char by dereferencing p are not. The compiler is
required to generate the correct code. However, at the time the code
is executed, if p happens to point to a string literal, the results
are undefined. Consider the slightly more general case:
int main(int argc, char *argv[]){
const char *pc = "Hello world";
char *p = "Hello world";
char a[] = "Hello world";
if (argc < 2)
p = a;
pc[0] = 'A'; /* diagnostic always required */
p[0] = 'A'; /* How would the compiler know? */
.....
return 0;
}

What does your compiler do with the above?

During execution, if argc is 2 or greater, the second assignment
statement results in undefined behavior. On a "good" system, the
program will fail at this point with an intelligible error message
indicating you attempted to modify a non-modifiable value. There are
systems where the program does fail at this point. Some may even
produce intelligible messages. However, both are beyond the scope of
the standard.

I wonder if there are any "really good" systems that can catch the
undefined behavior in
p = p++;
or
p = argv[argc+6];
Remove del for email
Dec 3 '06 #22

P: n/a
Keith Thompson <ks***@mib.orgwrote:
>
Making string literals const would have broken every single pre-ANSI
program that passed a string literal as an argument to a function
outside the standard library. Pre-ANSI C didn't have the "const"
keyword, so it wasn't possible to declare a parameter of type "const
char*". (I exclude the standard library because it can be updated
with "const" keywords along with the rest of the implementation.)
Except that, without overloading (which C doesn't have), there's no way
to make functions like strchr work right on both const and non-const
strings.

-Larry Jones

I told her to expect you to deny everything. -- Calvin

Dec 3 '06 #23

P: n/a
la************@ugs.com wrote:
Keith Thompson <ks***@mib.orgwrote:
>>Making string literals const would have broken every single pre-ANSI
program that passed a string literal as an argument to a function
outside the standard library. Pre-ANSI C didn't have the "const"
keyword, so it wasn't possible to declare a parameter of type "const
char*". (I exclude the standard library because it can be updated
with "const" keywords along with the rest of the implementation.)


Except that, without overloading (which C doesn't have), there's no way
to make functions like strchr work right on both const and non-const
strings.
How so?

It's perfectly legal and sane to pass a char* to a function that takes a
const char*

--
Ian Collins.
Dec 3 '06 #24

P: n/a
la************@ugs.com wrote:
Keith Thompson <ks***@mib.orgwrote:
>>
Making string literals const would have broken every single pre-ANSI
program that passed a string literal as an argument to a function
outside the standard library. Pre-ANSI C didn't have the "const"
keyword, so it wasn't possible to declare a parameter of type "const
char*". (I exclude the standard library because it can be updated
with "const" keywords along with the rest of the implementation.)

Except that, without overloading (which C doesn't have), there's no
way to make functions like strchr work right on both const and
non-const strings.
Nonsense. You can always pass a non-const string to a function
expecting a const string. The meaning of const in the parameter
list is that the function will not modify that string.

--
Chuck F (cbfalconer at maineline dot net)
Available for consulting/temporary embedded and systems.
<http://cbfalconer.home.att.net>
Dec 3 '06 #25

P: n/a
CBFalconer <cb********@yahoo.comwrites:
Dead Loop wrote:
>>
I understand that
1) I cannot modify the string by ^pointer p^ because it points to a
literal string.
2) I cannot modify the string by ^pointer p_const^ because first it is
(const char *) type and second it points to a literal string.
Am I right?

Who knows? You didn't quote anything. What is ^pointer p^
supposed to represent? I see no literal string. I see nothing of
type (const char *).
Chuck's point (which might not be clear to Dead Loop) is that Dead
Loop's article did not include enough context for the question to make
sense. Not everyone has easy access to the article to which you're
replying.

The Google Groups interface used to have a serious flaw that make it
difficult to provide sufficient context. The flaw has been corrected,
but <http://cfaj.freeshell.org/google/is still a very useful
explanation of the issues.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <* <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Dec 3 '06 #26

P: n/a
Barry Schwarz <sc******@doezl.netwrites:
[...]
The C standard distinguishes between violations of the language (for
which the compiler is required to issue a diagnostic and which are
often referred to as compile-time errors) and valid language
constructs which lead to undefined behavior (for which a diagnostic is
not required and which are referred to as run-time errors).
[...]

I don't think "run-time errors" is a good characterization of
undefined behavior. *Some* undefined behavior can certainly result in
run-time diagnostics (on some systems, in some circumstances), but a
compiler is free to diagnose undefined behavior during compilation.

Possible undefined behavior ranges from ignoring the situation
completely with unpredictable results, to behaving during
translation or program execution in a documented manner
characteristic of the environment (with or without the issuance of
a diagnostic message), to terminating a translation or execution
(with the issuance of a diagnostic message).

There are no required run-time diagnostics (other than functions
returning results that indicate that an error occurred).

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <* <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Dec 3 '06 #27

P: n/a
CBFalconer <cb********@yahoo.comwrites:
la************@ugs.com wrote:
>Keith Thompson <ks***@mib.orgwrote:
>>>
Making string literals const would have broken every single pre-ANSI
program that passed a string literal as an argument to a function
outside the standard library. Pre-ANSI C didn't have the "const"
keyword, so it wasn't possible to declare a parameter of type "const
char*". (I exclude the standard library because it can be updated
with "const" keywords along with the rest of the implementation.)

Except that, without overloading (which C doesn't have), there's no
way to make functions like strchr work right on both const and
non-const strings.

Nonsense. You can always pass a non-const string to a function
expecting a const string. The meaning of const in the parameter
list is that the function will not modify that string.
The problem is that strchr()'s return type should have the same
qualification, const-wise, as its argument, but C doesn't provide
a way to do that. (C++ does, via overloading.)
--
"If I've told you once, I've told you LLONG_MAX times not to
exaggerate."
--Jack Klein
Dec 3 '06 #28

P: n/a
Ben Pfaff wrote:
CBFalconer <cb********@yahoo.comwrites:
.... snip ...
>>
Nonsense. You can always pass a non-const string to a function
expecting a const string. The meaning of const in the parameter
list is that the function will not modify that string.

The problem is that strchr()'s return type should have the same
qualification, const-wise, as its argument, but C doesn't provide
a way to do that. (C++ does, via overloading.)
I guess it is a matter of viewpoint. What the caller does with the
return value is up to the caller. Meanwhile, we have the assurance
that strchr has not modified the string. It could actually be
quite awkward if the returned pointer was const, since anything as
simple as replacing a terminal '\n' would require casts. What is
really needed is a means of passing the constness, as viewed by the
caller, through the strchr routine. But we have no way of doing
this.

--
Chuck F (cbfalconer at maineline dot net)
Available for consulting/temporary embedded and systems.
<http://cbfalconer.home.att.net>

Dec 4 '06 #29

P: n/a
CBFalconer <cb********@yahoo.comwrites:
Ben Pfaff wrote:
>CBFalconer <cb********@yahoo.comwrites:
... snip ...
>>>
Nonsense. You can always pass a non-const string to a function
expecting a const string. The meaning of const in the parameter
list is that the function will not modify that string.

The problem is that strchr()'s return type should have the same
qualification, const-wise, as its argument, but C doesn't provide
a way to do that. (C++ does, via overloading.)

I guess it is a matter of viewpoint. What the caller does with the
return value is up to the caller. Meanwhile, we have the assurance
that strchr has not modified the string. It could actually be
quite awkward if the returned pointer was const, since anything as
simple as replacing a terminal '\n' would require casts. What is
really needed is a means of passing the constness, as viewed by the
caller, through the strchr routine. But we have no way of doing
this.
I think that's what I said.
--
"A lesson for us all: Even in trivia there are traps."
--Eric Sosman
Dec 4 '06 #30

P: n/a
Ben Pfaff wrote:
CBFalconer <cb********@yahoo.comwrites:
>Ben Pfaff wrote:
>>CBFalconer <cb********@yahoo.comwrites:
... snip ...
>>>>
Nonsense. You can always pass a non-const string to a function
expecting a const string. The meaning of const in the parameter
list is that the function will not modify that string.

The problem is that strchr()'s return type should have the same
qualification, const-wise, as its argument, but C doesn't provide
a way to do that. (C++ does, via overloading.)

I guess it is a matter of viewpoint. What the caller does with the
return value is up to the caller. Meanwhile, we have the assurance
that strchr has not modified the string. It could actually be
quite awkward if the returned pointer was const, since anything as
simple as replacing a terminal '\n' would require casts. What is
really needed is a means of passing the constness, as viewed by the
caller, through the strchr routine. But we have no way of doing
this.

I think that's what I said.
Yes, you did. What I was primarily addressing was the value of
returning a "const char*" rather than a "char *", using the system
as is. The last two sentences simply reworded your comment.

--
Chuck F (cbfalconer at maineline dot net)
Available for consulting/temporary embedded and systems.
<http://cbfalconer.home.att.net>

Dec 4 '06 #31

P: n/a
CBFalconer said:
la************@ugs.com wrote:
<snip>
>Except that, without overloading (which C doesn't have), there's no
way to make functions like strchr work right on both const and
non-const strings.

Nonsense. You can always pass a non-const string to a function
expecting a const string. The meaning of const in the parameter
list is that the function will not modify that string.
Sorry, Chuck, but I have a counter-example:

#include <stdio.h>
#include <string.h>

char *trust_me(const char *s)
{
size_t len = strlen(s);
char *p = strchr(s, '\0');
p -= len;
*p = 'D';
return p;
}

int main(void)
{
char arr[] = "Brain of Britain";
trust_me(arr);
printf("%s\n", arr);
return 0;
}

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at the above domain, - www.
Dec 4 '06 #32

P: n/a
Richard Heathfield wrote:
CBFalconer said:
>>la************@ugs.com wrote:

<snip>
>>>Except that, without overloading (which C doesn't have), there's no
way to make functions like strchr work right on both const and
non-const strings.

Nonsense. You can always pass a non-const string to a function
expecting a const string. The meaning of const in the parameter
list is that the function will not modify that string.

Sorry, Chuck, but I have a counter-example:

#include <stdio.h>
#include <string.h>

char *trust_me(const char *s)
{
size_t len = strlen(s);
char *p = strchr(s, '\0');
p -= len;
*p = 'D';
return p;
}

int main(void)
{
char arr[] = "Brain of Britain";
trust_me(arr);
printf("%s\n", arr);
return 0;
}
Another good reason to compile C code with a C++ compiler :)

--
Ian Collins.
Dec 4 '06 #33

P: n/a
Ian Collins said:
Richard Heathfield wrote:
>CBFalconer said:
>>>la************@ugs.com wrote:

<snip>
>>>>Except that, without overloading (which C doesn't have), there's no
way to make functions like strchr work right on both const and
non-const strings.

Nonsense. You can always pass a non-const string to a function
expecting a const string. The meaning of const in the parameter
list is that the function will not modify that string.

Sorry, Chuck, but I have a counter-example:

#include <stdio.h>
#include <string.h>

char *trust_me(const char *s)
{
size_t len = strlen(s);
char *p = strchr(s, '\0');
p -= len;
*p = 'D';
return p;
}

int main(void)
{
char arr[] = "Brain of Britain";
trust_me(arr);
printf("%s\n", arr);
return 0;
}
Another good reason to compile C code with a C++ compiler :)
Since I know of no good reasons to compile C code with a C++ compiler, I
baulked a little at "Another"; nevertheless, just as an experiment, I did
so, using g++ - and got no diagnostic messages whatsoever for the above
program (despite invoking the compiler in what I presume to be conforming
mode). And the output clearly showed that the modification of the array was
successful.

So this is not even a good reason to compile C code with a C++ compiler, let
alone another good reason.

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at the above domain, - www.
Dec 4 '06 #34

P: n/a
Richard Heathfield wrote:
>>
Another good reason to compile C code with a C++ compiler :)


Since I know of no good reasons to compile C code with a C++ compiler, I
baulked a little at "Another"; nevertheless, just as an experiment, I did
so, using g++ - and got no diagnostic messages whatsoever for the above
program (despite invoking the compiler in what I presume to be conforming
mode). And the output clearly showed that the modification of the array was
successful.
Then it's broken.
So this is not even a good reason to compile C code with a C++ compiler, let
alone another good reason.
CC x.c
"x.c", line 7: Error: Cannot use const char* to initialize char*.

The C++ standard states that strchr is replaced with two prototypes,

const char *strchr(const char *, int);
char *strchr(char *, int);

--
Ian Collins.
Dec 4 '06 #35

P: n/a
Ian Collins said:
Richard Heathfield wrote:
>>>
Another good reason to compile C code with a C++ compiler :)


Since I know of no good reasons to compile C code with a C++ compiler, I
baulked a little at "Another"; nevertheless, just as an experiment, I did
so, using g++ - and got no diagnostic messages whatsoever for the above
program (despite invoking the compiler in what I presume to be conforming
mode). And the output clearly showed that the modification of the array
was successful.
Then it's broken.
Fine - so that's yet another reason *not* to use it. :-)
--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at the above domain, - www.
Dec 4 '06 #36

P: n/a
Richard Heathfield wrote:
CBFalconer said:
.... snip ...
>>
Nonsense. You can always pass a non-const string to a function
expecting a const string. The meaning of const in the parameter
list is that the function will not modify that string.

Sorry, Chuck, but I have a counter-example:

#include <stdio.h>
#include <string.h>

char *trust_me(const char *s)
{
size_t len = strlen(s);
char *p = strchr(s, '\0');
p -= len;
*p = 'D';
return p;
}
Did anyone ever claim that C was a fool-proof language? If you
load both barrels, place the muzzle against your foot, and pull all
triggers, do you expect to retain said foot in a fleshy form for an
extended period of time? You didn't adhere to the promise you made
in the prototype.

--
Chuck F (cbfalconer at maineline dot net)
Available for consulting/temporary embedded and systems.
<http://cbfalconer.home.att.net>
Dec 4 '06 #37

P: n/a
CBFalconer said:
Richard Heathfield wrote:
>CBFalconer said:
... snip ...
>>>
Nonsense. You can always pass a non-const string to a function
expecting a const string. The meaning of const in the parameter
list is that the function will not modify that string.

Sorry, Chuck, but I have a counter-example:

#include <stdio.h>
#include <string.h>

char *trust_me(const char *s)
{
size_t len = strlen(s);
char *p = strchr(s, '\0');
p -= len;
*p = 'D';
return p;
}

You didn't adhere to the promise you made
in the prototype.
And yet I didn't break constness rules. (Which suggests to me that const is
broken.)

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at the above domain, - www.
Dec 4 '06 #38

P: n/a
Keith Thompson <ks***@mib.orgwrote:
Barry Schwarz <sc******@doezl.netwrites:
[...]
The C standard distinguishes between violations of the language (for
which the compiler is required to issue a diagnostic and which are
often referred to as compile-time errors) and valid language
constructs which lead to undefined behavior (for which a diagnostic is
not required and which are referred to as run-time errors).

I don't think "run-time errors" is a good characterization of
undefined behavior. *Some* undefined behavior can certainly result in
run-time diagnostics (on some systems, in some circumstances), but a
compiler is free to diagnose undefined behavior during compilation.
And OTOH, some undefined behaviour may not cause any visible errors at
all. Some may be accepted as an extension by a particular compiler, and
work predictably when used with that compiler (but not necessarily with
others). Some other UB may not cause any error messages or other
immediately obvious erroneous behaviour, but will be silently corrupting
data in the background, not detected until it's too late.

Richard
Dec 4 '06 #39

P: n/a
"Keith Thompson wrote:
"
CBFalconer <cb********@yahoo.comwrites:
Dead Loop wrote:
>
I understand that
1) I cannot modify the string by ^pointer p^ because it points to a
literal string.
2) I cannot modify the string by ^pointer p_const^ because first it is
(const char *) type and second it points to a literal string.
Am I right?
Who knows? You didn't quote anything. What is ^pointer p^
supposed to represent? I see no literal string. I see nothing of
type (const char *).

Chuck's point (which might not be clear to Dead Loop) is that Dead
Loop's article did not include enough context for the question to make
sense. Not everyone has easy access to the article to which you're
replying.

The Google Groups interface used to have a serious flaw that make it
difficult to provide sufficient context. The flaw has been corrected,
but <http://cfaj.freeshell.org/google/is still a very useful
explanation of the issues.
Sorry!
I'm an Usenet novice and I sometimes forget some Usenet netiquette.

My original question was:
Are there any differences between
char *p = "Hello, world!";
and
const char *p = "Hello, world!";
?

And after reading your articles, I understand that
If I define p & p_const in a function as follows:
char *p = "Hello, world!";
const char *p_const = "Hello, world!";
I'd better not modify the string by ^pointer p^ only because
it points to a literal string.
I'd better not modify the string by ^pointer p_const^ because
it points to a literal string and
I should not modify the string by ^pointer p_const^ because
it is (const char *) type.
Those are all the differences.
Am I right?

Dec 4 '06 #40

P: n/a
Dead Loop said:

<snip>
My original question was:
Are there any differences between
char *p = "Hello, world!";
and
const char *p = "Hello, world!";
?

And after reading your articles, I understand that
If I define p & p_const in a function as follows:
char *p = "Hello, world!";
const char *p_const = "Hello, world!";
I'd better not modify the string by ^pointer p^ only because
it points to a literal string.
Yes, that's the reason not to modify the string. It's nothing to do with the
pointer type's constness or otherwise, and everything to do with the fact
that modifying a string literal invokes undefined behaviour.

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at the above domain, - www.
Dec 4 '06 #41

P: n/a
"MQ" <mi**************@gmail.comwrote:
Dead Loop wrote:
Are there any differences between
char *p = "Hello, world!";
and
const char *p = "Hello, world!";

You shouldn't modify string literals, as it leads to undefined
behaviour. I believe on Windows platforms, string literals are kept in
a read-only data segment.
You believe wrong. On MS Windows as on any other system, where string
literals are put is up to the implementations, not up to the OS. It's
not surprising that many implementations do make use of a read-only part
of memory where one is available, but it is still up to them, not up to
the system.

Richard
Dec 5 '06 #42

This discussion thread is closed

Replies have been disabled for this discussion.