-2

char *s={'h','e','l','l','o','\0'}; --- gives a warning saying:

warning: (near initialization for ‘s’)
warning: excess elements in scalar initializer

But char *s="hello"; displays hello by allocating memory space for 6 characters in read only memory and s pointing to that specific location.

But what exactly is char *s={'h','e','l','l','o','\0'}; and how it is different?

Haris
  • 12,120
  • 6
  • 43
  • 70
kumar
  • 19
  • 1
  • 3
    `{ … }` is not itself an array, it's a braced initializer list. `char *s = { 'h', 'e', … }` is trying to initialize a pointer with the character `'h'` and discards the rest of the characters. (but all this can be deduced merely from the error message.) – The Paramagnetic Croissant Nov 13 '15 at 08:22

3 Answers3

2

A string literal like "hello" is treated as a pointer-to-char or an array-of-char depending on how you use it.

char *s = "hello";    // treats the string literal as pointer-to-char
char s[] = "hello";   // treats the string literal as array-of-char

An initializer like {'h','e','l','l','o','\0'} is treated as an array. It cannot be assigned to a pointer.

char *s = {'h','e','l','l','o','\0'};   // this is NOT valid
char s[] = {'h','e','l','l','o','\0'};  // same as char s[] = "hello"
user3386109
  • 34,287
  • 7
  • 49
  • 68
  • `treats the string literal as pointer-to-char` – no it doesn't, a string literal is always an array of `char`. It's just that arrays usually decay into pointers, and initialization of a pointer with an array is no exception. – The Paramagnetic Croissant Nov 13 '15 at 08:38
  • 1
    You are correct from a language lawyer point of view. But sometimes lawyer-speak obfuscates rather than illuminates. To my way of thinking, saying that *"it's an array that decays to a pointer"* is the same as saying that it's *"treated as a pointer"*. All I did was skip the intermediate step, and get right to the point. – user3386109 Nov 13 '15 at 08:44
0

The difference is that the "hello" is a string literal and {'h', 'e', 'l', 'l', 'o', '\0'} is a initializer list. The meaning of assigning a char* to a string literal is to just make the pointer point at the string, while the meaning of assigning char* to a initializer list is to just assign it to the first value (which is 'h' converted to a char*).

The proper way to use the initializer list is to use a char array instead:

char s[] = {'h', 'e', 'l', 'l', 'o', '\0'};

but still there is a difference here as this way you should end up with a mutable buffer. Here the initializer list is used as a list of values to initialize the element in the array with. It's a shortcut for:

char s[6];

s[0] = 'h';
s[1] = 'e';
s[2] = 'l';
s[3] = 'l';
s[4] = 'o';
s[5] = '\0';
skyking
  • 13,817
  • 1
  • 35
  • 57
  • 1
    "the meaning of...is to just assign it to the first value" - in Standard C it is *ill-formed*. Pointers may have at most one initializer. The behaviour you're describing is GCC extension. – M.M Nov 13 '15 at 08:48
  • Also a gcc extension is that `'h'` is treated as `(char *)'h'` – M.M Nov 13 '15 at 08:49
  • @M.M Your second comment I would say is incorrect. Both cases seem to be accepted by MSVC as well (so if they're extensions they are not very GCC specific). – skyking Nov 13 '15 at 09:00
0
#include <stdio.h>

int main (void) {

    char *s1 = "hello";                  /* creates a string literal   */
    char s2[] = {'h','e','l','l','o',0}; /* creates a character array  */

    printf ("\n s1 : %s\n s2 : %s\n\n", s1, s2);

    return 0;
}

Output

$ ./bin/s1s2

 s1 : hello
 s2 : hello

The primary difference between the character array 's2' and string literal 's1' is that the string literal is created and cannot later be changed. The character array can be used as any other array or null-terminated string.

David C. Rankin
  • 81,885
  • 6
  • 58
  • 85
  • it's not guaranteed that a string literal be placed in readonly memory; in fact, not even the existence of any sort of "readonly memory" is something the language is concerned with. – The Paramagnetic Croissant Nov 13 '15 at 08:37
  • I was talking from the dump for the file to assembly and the "hello" being happily in the *.rodata* section. – David C. Rankin Nov 13 '15 at 08:39
  • @DavidCRankin there's no assembly either in the question or in your answer whatsoever. This is a C language question which is about an abstract language construct that has nothing to do with assembly; consequently you are supposed to answer it from a C language point of view, and not from an assembly point of view. Infiltrating useless implementation details adds no value and only causes confusion, it doesn't clear it. – The Paramagnetic Croissant Nov 13 '15 at 08:41
  • 1
    Not worth the fight over semantics. – David C. Rankin Nov 13 '15 at 08:45
  • In C terms, writing over a string literal would be "undefined behavior". – Ian Abbott Nov 13 '15 at 12:21