Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.c > #55472 > unrolled thread
| Started by | arnuld <sunrise@invalid.address> |
|---|---|
| First post | 2014-12-27 05:37 +0000 |
| Last post | 2014-12-30 10:52 -0800 |
| Articles | 16 — 11 participants |
Back to article view | Back to comp.lang.c
string literals vs char* arnuld <sunrise@invalid.address> - 2014-12-27 05:37 +0000
Re: string literals vs char* Kaz Kylheku <kaz@kylheku.com> - 2014-12-27 06:36 +0000
Re: string literals vs char* Barry Schwarz <schwarzb@dqel.com> - 2014-12-27 00:58 -0800
Re: string literals vs char* Ian Collins <ian-news@hotmail.com> - 2014-12-27 22:03 +1300
Re: string literals vs char* Keith Thompson <kst-u@mib.org> - 2014-12-27 11:55 -0800
Re: string literals vs char* glen herrmannsfeldt <gah@ugcs.caltech.edu> - 2014-12-28 07:55 +0000
Re: string literals vs char* Ben Bacarisse <ben.usenet@bsb.me.uk> - 2014-12-28 11:39 +0000
Re: string literals vs char* Tim Rentsch <txr@alumni.caltech.edu> - 2015-03-24 08:55 -0700
Re: string literals vs char* Keith Thompson <kst-u@mib.org> - 2015-03-24 12:17 -0700
Re: string literals vs char* James Kuyper <jameskuyper@verizon.net> - 2014-12-27 11:36 -0500
Re: string literals vs char* Vincenzo Mercuri <nomail@yahoo.it> - 2014-12-27 18:20 +0100
Re: string literals vs char* Vincenzo Mercuri <nomail@yahoo.it> - 2014-12-27 18:55 +0100
Re: string literals vs char* Kaz Kylheku <kaz@kylheku.com> - 2014-12-27 17:25 +0000
Re: string literals vs char* Keith Thompson <kst-u@mib.org> - 2014-12-27 12:08 -0800
Re: string literals vs char* James Kuyper <jameskuyper@verizon.net> - 2014-12-28 07:01 -0500
Re: string literals vs char* John Bode <jfbode1029@gmail.com> - 2014-12-30 10:52 -0800
| From | arnuld <sunrise@invalid.address> |
|---|---|
| Date | 2014-12-27 05:37 +0000 |
| Subject | string literals vs char* |
| Message-ID | <549e45b4$0$280$14726298@news.sunsite.dk> |
C90 requires that string literls are constant, then why I am not getting
warning here. Is this a compiler problem ? (if it is a compiler problem
then why g++ catches the error at compile time when gccdoes not):
[arnuld@arch64 c $] cat test.c
#include<stdio.h>
int main(void)
{
char *p1 = "India", *p2;
p2=p1;
p1 = "BIX";
printf("%s %s\n", p1, p2);
return 0;
}
================== OUTPUT =======================
[arnuld@arch64 c $] gcc -ansi -pedantic -Wall -Wextra test.c
[arnuld@arch64 c $] ./a.out
BIX India
[arnuld@arch64 c $] g++ -ansi -pedantic -Wall -Wextra test.c
test.c: In function ‘int main()’:
test.c:5:16: warning: deprecated conversion from string constant to
‘char*’ [-Wwrite-strings]
char *p1 = "India", *p2;
^
test.c:7:8: warning: deprecated conversion from string constant to
‘char*’ [-Wwrite-strings]
p1 = "BIX";
^
[arnuld@arch64 c $]
--
arnuld
http://lispmachine.wordpress.com/
[toc] | [next] | [standalone]
| From | Kaz Kylheku <kaz@kylheku.com> |
|---|---|
| Date | 2014-12-27 06:36 +0000 |
| Message-ID | <20141226223301.119@kylheku.com> |
| In reply to | #55472 |
On 2014-12-27, arnuld <sunrise@invalid.address> wrote: > C90 requires that string literls are constant, then why I am not getting C90 makes it undefined behavior to modify a string literal. That is not exactly the same as "requires to be constant", and not the same as "requires a diagnostic". A string literal is an unqualified array of characters, which yields an unqualified pointer to char upon evaluation. > warning here. Is this a compiler problem ? (if it is a compiler problem > then why g++ catches the error at compile time when gccdoes not): Probably because the g++ front end configures GCC to compile some version of the C++ language, not C, let alone C90. In the C++ language, a string literal expression like "abc" has type "array [<size>] of const char", which evaluates to a "const char *" pointer to the first character.
[toc] | [prev] | [next] | [standalone]
| From | Barry Schwarz <schwarzb@dqel.com> |
|---|---|
| Date | 2014-12-27 00:58 -0800 |
| Message-ID | <ptss9a9fsoeqb304o4vmhht9qffb2414dg@4ax.com> |
| In reply to | #55472 |
On 27 Dec 2014 05:37:56 GMT, arnuld <sunrise@invalid.address> wrote:
>C90 requires that string literls are constant, then why I am not getting
>warning here. Is this a compiler problem ? (if it is a compiler problem
There is a difference between constant and const. String literals
have always been considered constant (modifying one causes undefined
behavior). However, for historical reasons (not breaking really old
code) they are not const. Hence no diagnostic. You are however free
to define the pointer properly as
const char *p1;
which would have no effect on the operation of your program.
>then why g++ catches the error at compile time when gccdoes not):
I don't use g++ but based on the text of the diagnostic, it appears
that g++ treats the literals as const due to the specified option
being in effect. If you compiled the program without that option, I
would expect the diagnostic to disappear.
>[arnuld@arch64 c $] cat test.c
>#include<stdio.h>
>
>int main(void)
>{
> char *p1 = "India", *p2;
> p2=p1;
> p1 = "BIX";
> printf("%s %s\n", p1, p2);
> return 0;
>}
>
>================== OUTPUT =======================
>[arnuld@arch64 c $] gcc -ansi -pedantic -Wall -Wextra test.c
>[arnuld@arch64 c $] ./a.out
>BIX India
>
>[arnuld@arch64 c $] g++ -ansi -pedantic -Wall -Wextra test.c
>test.c: In function ‘int main()’:
>test.c:5:16: warning: deprecated conversion from string constant to
>‘char*’ [-Wwrite-strings]
> char *p1 = "India", *p2;
> ^
>test.c:7:8: warning: deprecated conversion from string constant to
>‘char*’ [-Wwrite-strings]
> p1 = "BIX";
> ^
>[arnuld@arch64 c $]
--
Remove del for email
[toc] | [prev] | [next] | [standalone]
| From | Ian Collins <ian-news@hotmail.com> |
|---|---|
| Date | 2014-12-27 22:03 +1300 |
| Message-ID | <cg7avjF6itsU1@mid.individual.net> |
| In reply to | #55481 |
Barry Schwarz wrote: > On 27 Dec 2014 05:37:56 GMT, arnuld <sunrise@invalid.address> wrote: > >> C90 requires that string literls are constant, then why I am not getting >> warning here. Is this a compiler problem ? (if it is a compiler problem > > There is a difference between constant and const. String literals > have always been considered constant (modifying one causes undefined > behavior). However, for historical reasons (not breaking really old > code) they are not const. Hence no diagnostic. You are however free > to define the pointer properly as > const char *p1; > which would have no effect on the operation of your program. > >> then why g++ catches the error at compile time when gccdoes not): > > I don't use g++ but based on the text of the diagnostic, it appears > that g++ treats the literals as const due to the specified option > being in effect. If you compiled the program without that option, I > would expect the diagnostic to disappear. No, they would remain. g++ is a C++ compiler and C++ fixes C's const omissions. -- Ian Collins
[toc] | [prev] | [next] | [standalone]
| From | Keith Thompson <kst-u@mib.org> |
|---|---|
| Date | 2014-12-27 11:55 -0800 |
| Message-ID | <lnbnmozx3e.fsf@nuthaus.mib.org> |
| In reply to | #55481 |
Barry Schwarz <schwarzb@dqel.com> writes:
> On 27 Dec 2014 05:37:56 GMT, arnuld <sunrise@invalid.address> wrote:
>>C90 requires that string literls are constant, then why I am not getting
>>warning here. Is this a compiler problem ? (if it is a compiler problem
>
> There is a difference between constant and const. String literals
> have always been considered constant (modifying one causes undefined
> behavior). However, for historical reasons (not breaking really old
> code) they are not const. Hence no diagnostic. You are however free
> to define the pointer properly as
> const char *p1;
> which would have no effect on the operation of your program.
All this applies to C90, C99, and C11.
Yes, there's a difference between constant and const, but you haven't
stated it correctly.
A *constant expression* is one that can be (and in some cases must be)
evaluated at compile time. (And a "constant", used as a noun, is a
token in source code, referred to in some languages as a "literal".)
The "const" keyword, on the other hand, means read-only.
String literals are read-only, but as you say they're not made "const"
for historical reasons. Attempting to modifying a string literal has
undefined beahvior, but you can't count on the compiler to diagnose the
attempt.
Some pre-ANSI C compilers, IIRC, actually allowed you to modify string
literals, so that this:
char *s = "hello";
s[0] = 'H';
puts(s);
would actually print "Hello". (It might also affect other uses of the
same string literal.) And in fact a conforming C11 compiler could do
the same thing; the behavior is undefined, so it can do anything it
likes.
>>then why g++ catches the error at compile time when gcc does not):
Because g++ is a C++ compiler, and in C++ string literals are const.
> I don't use g++ but based on the text of the diagnostic, it appears
> that g++ treats the literals as const due to the specified option
> being in effect. If you compiled the program without that option, I
> would expect the diagnostic to disappear.
>
>>[arnuld@arch64 c $] cat test.c
>>#include<stdio.h>
>>
>>int main(void)
>>{
>> char *p1 = "India", *p2;
>> p2=p1;
>> p1 = "BIX";
>> printf("%s %s\n", p1, p2);
>> return 0;
>>}
>>
>>================== OUTPUT =======================
>>[arnuld@arch64 c $] gcc -ansi -pedantic -Wall -Wextra test.c
>>[arnuld@arch64 c $] ./a.out
>>BIX India
>>
>>[arnuld@arch64 c $] g++ -ansi -pedantic -Wall -Wextra test.c
>>test.c: In function ‘int main()’:
>>test.c:5:16: warning: deprecated conversion from string constant to
>>‘char*’ [-Wwrite-strings]
>> char *p1 = "India", *p2;
>> ^
>>test.c:7:8: warning: deprecated conversion from string constant to
>>‘char*’ [-Wwrite-strings]
>> p1 = "BIX";
>> ^
>>[arnuld@arch64 c $]
--
Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.net/~kst>
Working, but not speaking, for JetHead Development, Inc.
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
[toc] | [prev] | [next] | [standalone]
| From | glen herrmannsfeldt <gah@ugcs.caltech.edu> |
|---|---|
| Date | 2014-12-28 07:55 +0000 |
| Message-ID | <m7od1e$rnv$1@speranza.aioe.org> |
| In reply to | #55506 |
Keith Thompson <kst-u@mib.org> wrote:
(snip)
> All this applies to C90, C99, and C11.
> Yes, there's a difference between constant and const, but you haven't
> stated it correctly.
> A *constant expression* is one that can be (and in some cases must be)
> evaluated at compile time. (And a "constant", used as a noun, is a
> token in source code, referred to in some languages as a "literal".)
(snip)
> Some pre-ANSI C compilers, IIRC, actually allowed you to modify string
> literals, so that this:
> char *s = "hello";
> s[0] = 'H';
> puts(s);
I don't have my K&R1 nearby, but I thought I remember that it
specifically allowed for this.
A fair number of compilers might still allow it, if they don't test
for it, and don't keep constants in write protected storage.
> would actually print "Hello". (It might also affect other uses of the
> same string literal.) And in fact a conforming C11 compiler could do
> the same thing; the behavior is undefined, so it can do anything it
> likes.
Yes, a compiler that specifically allowed it should keep all string
constants stored separately.
But as the OP wrote:
>>>[arnuld@arch64 c $] cat test.c
>>>#include<stdio.h>
>>>
>>>int main(void)
>>>{
>>> char *p1 = "India", *p2;
>>> p2=p1;
>>> p1 = "BIX";
>>> printf("%s %s\n", p1, p2);
>>> return 0;
>>>}
It seems to me that this doesn't actually modify any constants.
-- glen
[toc] | [prev] | [next] | [standalone]
| From | Ben Bacarisse <ben.usenet@bsb.me.uk> |
|---|---|
| Date | 2014-12-28 11:39 +0000 |
| Message-ID | <87k31cdmv4.fsf@bsb.me.uk> |
| In reply to | #55539 |
glen herrmannsfeldt <gah@ugcs.caltech.edu> writes: > Keith Thompson <kst-u@mib.org> wrote: > > (snip) > >> All this applies to C90, C99, and C11. > >> Yes, there's a difference between constant and const, but you haven't >> stated it correctly. > >> A *constant expression* is one that can be (and in some cases must be) >> evaluated at compile time. (And a "constant", used as a noun, is a >> token in source code, referred to in some languages as a "literal".) > > (snip) > >> Some pre-ANSI C compilers, IIRC, actually allowed you to modify string >> literals, so that this: > >> char *s = "hello"; >> s[0] = 'H'; >> puts(s); > > I don't have my K&R1 nearby, but I thought I remember that it > specifically allowed for this. I can't find any explicit text either way, but that suggests, to me, that the arrays denoted by string literals are just like any other (K&R) C arrays and may be modified. Further evidence comes form that fact the K&R1 does say that all strings, even when written identically, are distinct. That's not conclusive, but sharing between similar strings is one reason to make writing to them undefined. <snip> -- Ben.
[toc] | [prev] | [next] | [standalone]
| From | Tim Rentsch <txr@alumni.caltech.edu> |
|---|---|
| Date | 2015-03-24 08:55 -0700 |
| Message-ID | <kfnr3seie4o.fsf@x-alumni2.alumni.caltech.edu> |
| In reply to | #55541 |
Ben Bacarisse <ben.usenet@bsb.me.uk> writes:
> glen herrmannsfeldt <gah@ugcs.caltech.edu> writes:
>
>> Keith Thompson <kst-u@mib.org> wrote:
>>
>> (snip)
>>
>>> All this applies to C90, C99, and C11.
>>>
>>> Yes, there's a difference between constant and const, but you haven't
>>> stated it correctly.
>>>
>>> A *constant expression* is one that can be (and in some cases must be)
>>> evaluated at compile time. (And a "constant", used as a noun, is a
>>> token in source code, referred to in some languages as a "literal".)
>>
>> (snip)
>>
>>> Some pre-ANSI C compilers, IIRC, actually allowed you to modify string
>>> literals, so that this:
>>>
>>> char *s = "hello";
>>> s[0] = 'H';
>>> puts(s);
>>
>> I don't have my K&R1 nearby, but I thought I remember that it
>> specifically allowed for this.
>
> I can't find any explicit text either way, but that suggests, to me,
> that the arrays denoted by string literals are just like any other (K&R)
> C arrays and may be modified.
>
> Further evidence comes form that fact the K&R1 does say that all
> strings, even when written identically, are distinct. That's not
> conclusive, but sharing between similar strings is one reason to make
> writing to them undefined.
For those who are interested:
At the time that the C89 committee was working, writable
string literals weren't "legacy code" (Margolin) and what
standard there existed (K&R 1) was quite explicit (A.2.5)
that strings were just a way of initializing a static array.
And as Barry pointed out there were some (mktemp) routines
that used this fact.
This comment comes from a comp.std.c posting in 1998, written
by Dennis Ritchie.
[toc] | [prev] | [next] | [standalone]
| From | Keith Thompson <kst-u@mib.org> |
|---|---|
| Date | 2015-03-24 12:17 -0700 |
| Message-ID | <87iodqryqg.fsf@kst-u.example.com> |
| In reply to | #58841 |
Tim Rentsch <txr@alumni.caltech.edu> writes:
> Ben Bacarisse <ben.usenet@bsb.me.uk> writes:
>> glen herrmannsfeldt <gah@ugcs.caltech.edu> writes:
>>> Keith Thompson <kst-u@mib.org> wrote:
>>> (snip)
>>>
>>>> All this applies to C90, C99, and C11.
>>>>
>>>> Yes, there's a difference between constant and const, but you haven't
>>>> stated it correctly.
>>>>
>>>> A *constant expression* is one that can be (and in some cases must be)
>>>> evaluated at compile time. (And a "constant", used as a noun, is a
>>>> token in source code, referred to in some languages as a "literal".)
>>>
>>> (snip)
>>>
>>>> Some pre-ANSI C compilers, IIRC, actually allowed you to modify string
>>>> literals, so that this:
>>>>
>>>> char *s = "hello";
>>>> s[0] = 'H';
>>>> puts(s);
>>>
>>> I don't have my K&R1 nearby, but I thought I remember that it
>>> specifically allowed for this.
>>
>> I can't find any explicit text either way, but that suggests, to me,
>> that the arrays denoted by string literals are just like any other (K&R)
>> C arrays and may be modified.
>>
>> Further evidence comes form that fact the K&R1 does say that all
>> strings, even when written identically, are distinct. That's not
>> conclusive, but sharing between similar strings is one reason to make
>> writing to them undefined.
>
> For those who are interested:
>
> At the time that the C89 committee was working, writable
> string literals weren't "legacy code" (Margolin) and what
> standard there existed (K&R 1) was quite explicit (A.2.5)
> that strings were just a way of initializing a static array.
> And as Barry pointed out there were some (mktemp) routines
> that used this fact.
>
> This comment comes from a comp.std.c posting in 1998, written
> by Dennis Ritchie.
I happen to have my copy of K&R1 handy. Appendix A is the C Reference
Manual. A.2.5 says:
A string is a sequence of characters surrounded by double quotes, as
in "...". A string has type "array of characters" and storage class
static (see section 4 below) and is initialized with the given
characters. All strings, even when written identically, are
distinct. [...]
I do not guarantee that I haven't introduced any typos.
There was no notion of "const", so the array was implicitly writable.
A.2.5 uses the term "string" to refer both to what we would now call a
"string literal" (K&R1 uses the phrase "string constant" elsewhere), and
to corresponding the static array that exists during program execution.
--
Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.net/~kst>
Working, but not speaking, for JetHead Development, Inc.
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
[toc] | [prev] | [next] | [standalone]
| From | James Kuyper <jameskuyper@verizon.net> |
|---|---|
| Date | 2014-12-27 11:36 -0500 |
| Message-ID | <m7mn61$pti$1@dont-email.me> |
| In reply to | #55472 |
On 12/27/2014 12:37 AM, arnuld wrote:
> C90 requires that string literls are constant, then why I am not getting
> warning here.
It does not require that they be constant. It says that the behavior is
undefined if you attempt to modify them. "undefined behavior" is a piece
of jargon defined by the C standard. It is NOT a requirement, rather, it
identifies a complete absence of requirements imposed by the C standard.
There have been real implementations where the program would abort() if
such code were executed, and other implementations where executing that
code would cause the memory containing the string literal to be
modified. In principle, there could be implementations which silently
converted such operations into no-ops, though I'm not personally aware
of any. As there is a complete absence of requirements imposed by the C
standard on such code, all three behaviors are permitted for a
conforming implementation.
String literals have the type char[n], where n is 1 more than the number
characters in the string literal, and in most contexts are converted
into pointers to the first element of that array. That pointer has the
type 'char*'. As a result, your code doesn't violate any constraints.
> ... Is this a compiler problem ? (if it is a compiler problem
> then why g++ catches the error at compile time when gccdoes not):
The type of a string literal should have been "const char[n]", But C was
designed long before the 'const' keyword was added, and far too much
legacy code would have had to be re-written if they had changed that
rule when 'const' was added. 'const' was invented for C++, and ported
back to C, and in C++ string literals have been const-qualified almost
from the very beginning.
> [arnuld@arch64 c $] cat test.c
> #include<stdio.h>
>
> int main(void)
> {
> char *p1 = "India", *p2;
A sufficiently helpful C compiler could warn about that initialization,
but there's nothing in the C standard that mandates it.
> p2=p1;
> p1 = "BIX";
The same is true about that assignment.
--
James Kuyper
[toc] | [prev] | [next] | [standalone]
| From | Vincenzo Mercuri <nomail@yahoo.it> |
|---|---|
| Date | 2014-12-27 18:20 +0100 |
| Message-ID | <-PGdndU0S8__dwPJnZ2dnUU7-TGdnZ2d@giganews.com> |
| In reply to | #55491 |
Il 27/12/2014 18:02, Stefan Ram ha scritto:
> James Kuyper <jameskuyper@verizon.net> writes:
>> String literals have the type char[n], where n is 1 more than the number
>
> »N1570 6.4.5 String literals« does say that »The multibyte
> character sequence is then used to initialize an array of
> static storage duration and length just sufficient to
> contain the sequence«, but it does not name the type as
> »char[n]«. [..]
Right after the part you quoted it says:
"For character string literals, the array elements
have type char, and are initialized with the individual
bytes of the multibyte character sequence."
--
Vincenzo Mercuri
[toc] | [prev] | [next] | [standalone]
| From | Vincenzo Mercuri <nomail@yahoo.it> |
|---|---|
| Date | 2014-12-27 18:55 +0100 |
| Message-ID | <-PGdndQ0S88AbwPJnZ2dnUU7-TGdnZ2d@giganews.com> |
| In reply to | #55494 |
Il 27/12/2014 18:25, Stefan Ram ha scritto: > Vincenzo Mercuri <nomail@yahoo.it> writes: >> Il 27/12/2014 18:02, Stefan Ram ha scritto: >>> James Kuyper <jameskuyper@verizon.net> writes: >>>> String literals have the type char[n], where n is 1 more than the number >>> »N1570 6.4.5 String literals« does say that »The multibyte >>> character sequence is then used to initialize an array of >>> static storage duration and length just sufficient to >>> contain the sequence«, but it does not name the type as >>> »char[n]«. [..] >> Right after the part you quoted it says: >> "For character string literals, the array elements >> have type char, and are initialized with the individual >> bytes of the multibyte character sequence." > > This says that the elements of the array being described > have type char, but it does not explicitly say that this > array is the value of the string literal or what the type of > the string literal is. It merely seems to invite the reader > to guess that this might be so. > Mmm.. I think I understand your point, even though it looks clear to me that we are talking about a char[] with static storage duration. That: >>> [..] »The multibyte >>> character sequence is then used to initialize an array of [..] plus: >> [..] the array elements >> have type char, and are initialized with the individual [..] given that we are in section "Semantics" and we are specifically talking about translation phases, honestly leaves no doubt to me. -- Vincenzo Mercuri
[toc] | [prev] | [next] | [standalone]
| From | Kaz Kylheku <kaz@kylheku.com> |
|---|---|
| Date | 2014-12-27 17:25 +0000 |
| Message-ID | <20141227092433.485@kylheku.com> |
| In reply to | #55491 |
On 2014-12-27, Stefan Ram <ram@zedat.fu-berlin.de> wrote: > James Kuyper <jameskuyper@verizon.net> writes: >>String literals have the type char[n], where n is 1 more than the number > > »N1570 6.4.5 String literals« does say that »The multibyte > character sequence is then used to initialize an array of > static storage duration and length just sufficient to > contain the sequence«, but it does not name the type as > »char[n]«. While you are probably right, I cannot find > this type explicitly given in N1570. Well, *something* has to explain why sizeof "abcd" is five, in any case, right? :)
[toc] | [prev] | [next] | [standalone]
| From | Keith Thompson <kst-u@mib.org> |
|---|---|
| Date | 2014-12-27 12:08 -0800 |
| Message-ID | <ln7fxczwij.fsf@nuthaus.mib.org> |
| In reply to | #55491 |
ram@zedat.fu-berlin.de (Stefan Ram) writes:
> James Kuyper <jameskuyper@verizon.net> writes:
>>String literals have the type char[n], where n is 1 more than the number
>
> »N1570 6.4.5 String literals« does say that »The multibyte
> character sequence is then used to initialize an array of
> static storage duration and length just sufficient to
> contain the sequence«, but it does not name the type as
> »char[n]«. While you are probably right, I cannot find
> this type explicitly given in N1570. (Surely, it says that
> (char []){"/tmp/fileXXXXXX"} has this type.) I am not sure
> whether it even says that the /value/ of a string literal
> is this array. Maybe this is taken for granted?
>
> I wish, however, that a formal specification would contain
> wordings of the kind of: »The value of a string literal is
> ...« and »The type of a string literal is ...«, and that
> these wordings would bein the section titled »String
> literals«. To achieve this, the best way is for every type
> of expression and function to always explicitly give: value,
> type, and effect - even if »none« or »unspecified«. (The new
> C++ specifications get this a little bit better, because for
> every function there is a separate section labeled »effect«
> [if it has an effect].)
[...]
6.5.1 "Primary expressions" paragraph 4 says:
A string literal is a primary expression. It is an lvalue with
type as detailed in 6.4.5.
6.4.5p6 says:
... The multibyte character sequence is then used to initialize
an array of static storage duration and length just sufficient
to contain the sequence. For character string literals, the
array elements have type char, and are initialized with the
individual bytes of the multibyte character sequence.
which I think is sufficient to specify that the string literal
"hello" is an lvalue of type char[6].
But I still don't see an explicit statement that the object
designated by the lvalue is actually the array object described
in 6.5.4. That's the only sane interpretation, but unless I'm
missing something (which is a very real possibility) it's not
explicitly stated.
--
Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.net/~kst>
Working, but not speaking, for JetHead Development, Inc.
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
[toc] | [prev] | [next] | [standalone]
| From | James Kuyper <jameskuyper@verizon.net> |
|---|---|
| Date | 2014-12-28 07:01 -0500 |
| Message-ID | <m7ordu$f5r$1@dont-email.me> |
| In reply to | #55491 |
On 12/27/2014 12:02 PM, Stefan Ram wrote:
> James Kuyper <jameskuyper@verizon.net> writes:
>> String literals have the type char[n], where n is 1 more than the number
>
> �N1570 6.4.5 String literals� does say that �The multibyte
> character sequence is then used to initialize an array of
> static storage duration and length just sufficient to
> contain the sequence�, but it does not name the type as
> �char[n]�. While you are probably right, I cannot find
> this type explicitly given in N1570. (Surely, it says that
> (char []){"/tmp/fileXXXXXX"} has this type.) I am not sure
> whether it even says that the /value/ of a string literal
> is this array. Maybe this is taken for granted?
I would say that it is implied by the words that you cite, rather than
being taken for granted. As usual, I wouldn't mind it if the implication
was spelled out more clearly.
--
James Kuyper
[toc] | [prev] | [next] | [standalone]
| From | John Bode <jfbode1029@gmail.com> |
|---|---|
| Date | 2014-12-30 10:52 -0800 |
| Message-ID | <6bffde47-a6d7-4d9f-9048-802f80c0c051@googlegroups.com> |
| In reply to | #55472 |
On Friday, December 26, 2014 11:38:08 PM UTC-6, arnuld wrote:
> C90 requires that string literls are constant, then why I am not getting
> warning here. Is this a compiler problem ? (if it is a compiler problem
> then why g++ catches the error at compile time when gccdoes not):
>
C and C++ are different languages with different rules. A legal C program
doesn't have to be a legal C++ program, nor does it have to have identical
behavior.
>
> [arnuld@arch64 c $] cat test.c
> #include<stdio.h>
>
> int main(void)
> {
> char *p1 = "India", *p2;
> p2=p1;
> p1 = "BIX";
Note that you are only updating the value of p1 to point to a different
string; you are not modifying the string literal "India".
Assume the following memory map (addresses are pulled out of thin
air and not meant to represent any real-world platform):
Item Address 0x01 0x02 0x03 0x04
---- ------- ---- ---- ---- ----
"India" 0x8000 'I' 'n' 'd' 'i'
0x8004 'a' 0x00 ??? ???
"BIX" 0x8008 'B' 'I' 'X' 0x00
...
p1 0xfff0 0x00 0x00 0x80 0x00
When you start out, p1 contains the address of the string literal "India"
(0x8000). The line
p1 = "BIX";
simply assigns the new address 0x8008 to p1.
> printf("%s %s\n", p1, p2);
> return 0;
> }
>
> ================== OUTPUT =======================
> [arnuld@arch64 c $] gcc -ansi -pedantic -Wall -Wextra test.c
> [arnuld@arch64 c $] ./a.out
> BIX India
>
> [arnuld@arch64 c $] g++ -ansi -pedantic -Wall -Wextra test.c
> test.c: In function 'int main()':
> test.c:5:16: warning: deprecated conversion from string constant to
> 'char*' [-Wwrite-strings]
> char *p1 = "India", *p2;
> ^
> test.c:7:8: warning: deprecated conversion from string constant to
> 'char*' [-Wwrite-strings]
> p1 = "BIX";
> ^
In C++, string literals are arrays of type "const char". thus those
expressions decay to type "const char *". The g++ compiler is complaining
because you are trying to assign a "const char *" value to a "char *"
variable; you're discarding the "const" qualifier, hence the warning.
[toc] | [prev] | [standalone]
Back to top | Article view | comp.lang.c
csiph-web