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?
Compile-time errors are the errors that occurred when we write the wrong syntax. If we write the wrong syntax or semantics of any programming language, then the compile-time errors will be thrown by the compiler. The compiler will not allow to run the program until all the errors are removed from the program.
A checked exception is caught at compile time whereas a runtime or unchecked exception is, as it states, at runtime. A checked exception must be handled either by re-throwing or with a try catch block, whereas an unchecked isn't required to be handled.
A runtime error is a program error that occurs while the program is running. Whereas, a syntax error is an error in the syntax of a sequence of characters or tokens that is intended to be written in a particular programming language. Thus, this is the main difference between Run Time Error and Syntax Error.
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).
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With