5
char *s = "hello";

The code above allocates 6 bytes in read-only section of a program (I've forgot the name of the section) to store the string hello. Then, s is initialized to point to the first character of the string hello. Modifying the string "hello" is undefined behavior. Besides, "hello" itself is constant in nature. The program doesn't have permission to change read-only section.

I'm using MS VC++ 2010 Express. My question is, why does the compiler allows s, which is a char *, to point to the constant string? Shouldn't there be a compiler error? Shouldn't the compiler force us to use const char *s = "hello"; instead of char *s = "hello";?

Thanks.

Donotalo
  • 12,748
  • 25
  • 83
  • 121

2 Answers2

5

In C, "hello" has type char[]. This is not C++. See this question.

Community
  • 1
  • 1
Pascal Cuoq
  • 79,187
  • 7
  • 161
  • 281
  • @samold I am not sure what you mean. If you mean that I should have simply voted the question as a duplicate, my feeling here is that the question is different enough, although the very complete answer there covers the question here. Anyway, others can close the question as a duplicate if they feel it is one. – Pascal Cuoq Nov 18 '11 at 08:31
  • Sorry mate, I just love Phil Ken Sebben. :) – sarnold Nov 18 '11 at 08:32
  • @samold Oh, I see. This avatar picture was chosen by the other StackExchange user whose OpenID finds itself attached to this unwillingly shared account. – Pascal Cuoq Nov 18 '11 at 08:35
  • Sheeeesh, that sounds horrible. Flag for moderator attention, they've worked out similar things in the past... – sarnold Nov 18 '11 at 08:37
  • 2
    To avoid confusions, it has type char[N] where N is the length of the literal +1. – Johannes Schaub - litb Nov 18 '11 at 08:40
  • @Complicatedseebio: Indeed, flag for attention or (probably better) email asking for help. When I first joined SO I had a problem with my account becoming inaccessible (cookie problem) before I setup OpenID and they fixed it right away. If they hadn't been so responsive I probably wouldn't still be with SO today. – R.. GitHub STOP HELPING ICE Nov 18 '11 at 14:54
2

This predates the times when the const qualifier was introduced to C. The C standards body is very conservative with respect to existing code. Any improvement of the language is required to be done in such a way that it wouldn't break any existing conforming code that is written for the previous version of the standard.

If such things then lead to undesirable complications, the feature is then deprecated and maybe changed years after that.

For the concrete feature of string literals being typed char[] instead of char const[], yes this is unfortunately a pitfall for beginners. Just get the habit from the start to use char const* whenever you reference such strings.

Edit: For the question if a compiler could or should warn about that, I think this is just difficult to trace. In this code

int main(void) {
  "hello"[0] = 'H';
  char * a = "hoho";
  a[0] = 'H';
}

gcc only gives me a warning on the first assignement, not on the second. clang doesn't capture it at all.

Jens Gustedt
  • 76,821
  • 6
  • 102
  • 177
  • They are right to do so, but in the said case, it would be enough to emit a warning. That's not what I would consider "breaking old code". – glglgl Nov 18 '11 at 08:48
  • 1
    To be precise, the array associated with a string literal is of type `char[N]`, but any attempt to modify it has undefined behavior. (gcc, for example, can be told to treat string literals as const with the `-Wwrite-strings` option, but this is non-conforming.) – Keith Thompson Nov 18 '11 at 09:19
  • @glglgl, I do completely agree, but don't think that this is trivial. Please see my edit. – Jens Gustedt Nov 18 '11 at 09:43