Anup Buchke
Anup Buchke

Reputation: 5520

Compile Time Error vs Run Time Error

I am confused why compiler gives

const char s[]="hello";
s[2]='t';                 // Compile Time Error

char *t = "hello";
*(t+2)='u';              // Run time Error

I guess in both case the compiler should give compile time error. Can anyone tell me particular reason for this to be this way?

Upvotes: 5

Views: 3604

Answers (4)

In the first case, you are writing to a const and the compiler notices that and can reject that.

In the second case, t is a pointer to a non-const char, so you can dereference it and write at *(t+2). However, since t is initialized with a pointer to a read-only segment, you are getting a segmentation violation at runtime.

You could painfully configure your linker to put all data in writable segments. This is ugly and non standard.

P.S. Some sophisticated static analyzers (maybe Frama-C) might catch both errors without running the program. One could also imagine extending GCC e.g. with MELT to add such checks (but this is non-trivial work, and it might be hard to get funded for it).

Upvotes: 6

Corbin
Corbin

Reputation: 33457

Backwards compatibility.

You can't modify a const char. That much is obvious.

What isn't obvious is that the type of a string literal is actually a pointer to constant characters, not a pointer to characters. The second declaration, actually, therefore has a wrong type. This is supported, however, for historical reasons.


Note that the above is a bit of a lie. Rather than pointers, string literals are actually char[] types.

In particular, the type of a string literal is a char[] rather than a const char[] in C89 and C99 [and I think C11, not sure though]. It's not actually wrong then, but the data is stored in a read only segment, so it's undefined behavior to try to write to it.


Also, for what it's worth, you can use -Wwrite-strings with gcc (g++ already includes it) to be warned of this.


More information here and here.

Upvotes: 6

Maroun
Maroun

Reputation: 95998

When you do: char *t = "hello"; then t is a pointer that points to a memory that is in the code part, so you can't change it. Because it's read-only, you're getting segmentation fault at runtime.

When you do: const char s[]="hello"; then s is an array of chars that are on the stack, but it's const, so you can't change it and you get a compilation error (The compiler knows it is const so he doesn't allow you to change it).

Using const when you don't want your String to be changed is good because this arise a compilation error, which is a way better than a run time error.

Upvotes: 3

uba
uba

Reputation: 2031

Consider the following series of statements:

char *t = "hello";
char s[5];
t = s;
*(t+2)='u';

This series of statements will give no run time error, because the statement *(t+2)='u'; is not invalid. It is trying to modify a const (read-only) memory location in your case, but the compiler has no way of knowing whether an access violation will occur.

Upvotes: 2

Related Questions