I have code equivalent to the following:
const int* const n = new int;
printf("input: ");
scanf("%d", n);
delete n;
Now, since n is a pointer to a CONSTANT integer, this shouldn't work (I'm expecting a compiler error). However, this seems to work properly and even stores the value of the input into *n.
I want to know, why doesn't this give me an error; why does it work? Shouldn't scanf be unable to alter the value of *n?
Yes, it's supposed to have constant value, but it doesn't magically guarantee it. You took an address of this variable (of type const int * ) which is nothing more than a number pointing to some memory.
const int* const says that the pointer can point to a constant int and value of int pointed by this pointer cannot be changed. And we cannot change the value of pointer as well it is now constant and it cannot point to another constant int. Thumb rule is to naming syntax from right to left.
const int * And int const * are the same. const int * const And int const * const are the same. If you ever face confusion in reading such symbols, remember the Spiral rule: Start from the name of the variable and move clockwise to the next pointer or type. Repeat until expression ends.
The first const keyword can go either side of data type, hence int const* is equivalent to const int*.
The prototype for scanf is:
int scanf ( const char * format, ... );
The ellipsis means it takes variable arguments. C (and C++) have no way to check the validity of these parameters. That's why you won't get an error if you pass the address of a double here or even the double variable itself. It's up to the programmer to verify the correct parameter is passed.
scanf
has next to no type safety, it merrily does what you tell it to. This is because of the way variable-argument lists are implemented in C. They expect the types to be of the kind which you tell it.
So if you give scanf
a conversion specifier which doesn't match, you will invoke undefined behavior, which occurs in run-time. Similarly, there is probably no way for the compiler to tell that the pointer passed is of type const type* const
. A good compiler may give a diagnostic if it spots something fishy, but is by no means required to do so.
Since most cases of undefined behavior occur in run-time, it is generally the programmer's responsibility to know about the various forms of undefined behavior and avoid them.
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