Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

scanf with const int* const works, but shouldn't

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?

like image 343
Crazycolorz5 Avatar asked Oct 27 '15 13:10

Crazycolorz5


People also ask

Can we use Scanf for constant?

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.

Can INT and const be used together in C?

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.

What is the difference between int * const C and const int * C?

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.

Can const and int be used together?

The first const keyword can go either side of data type, hence int const* is equivalent to const int*.


2 Answers

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.

like image 128
pcarter Avatar answered Oct 01 '22 01:10

pcarter


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.

like image 31
Lundin Avatar answered Oct 01 '22 01:10

Lundin