Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.c > #55472 > unrolled thread

string literals vs char*

Started byarnuld <sunrise@invalid.address>
First post2014-12-27 05:37 +0000
Last post2014-12-30 10:52 -0800
Articles 16 — 11 participants

Back to article view | Back to comp.lang.c


Contents

  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

#55472 — string literals vs char*

Fromarnuld <sunrise@invalid.address>
Date2014-12-27 05:37 +0000
Subjectstring 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]


#55476

FromKaz Kylheku <kaz@kylheku.com>
Date2014-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]


#55481

FromBarry Schwarz <schwarzb@dqel.com>
Date2014-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]


#55482

FromIan Collins <ian-news@hotmail.com>
Date2014-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]


#55506

FromKeith Thompson <kst-u@mib.org>
Date2014-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]


#55539

Fromglen herrmannsfeldt <gah@ugcs.caltech.edu>
Date2014-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]


#55541

FromBen Bacarisse <ben.usenet@bsb.me.uk>
Date2014-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]


#58841

FromTim Rentsch <txr@alumni.caltech.edu>
Date2015-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]


#58864

FromKeith Thompson <kst-u@mib.org>
Date2015-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]


#55491

FromJames Kuyper <jameskuyper@verizon.net>
Date2014-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]


#55494

FromVincenzo Mercuri <nomail@yahoo.it>
Date2014-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]


#55498

FromVincenzo Mercuri <nomail@yahoo.it>
Date2014-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]


#55496

FromKaz Kylheku <kaz@kylheku.com>
Date2014-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]


#55507

FromKeith Thompson <kst-u@mib.org>
Date2014-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]


#55545

FromJames Kuyper <jameskuyper@verizon.net>
Date2014-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]


#55592

FromJohn Bode <jfbode1029@gmail.com>
Date2014-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