16

I had an interview in which they had asked me this question

#include<stdio.h>
int main ()
{
int* const p=NULL;
int const *q=NULL;
p++;
q++;
printf("%d\n",p);
printf("%d\n",q);
}

How will above program behave

a) p will increment 4 bytes;
and q will also increment 4 bytes;

b) p will be zero
q will point to memory 4 bytes ahead;

c) error will come in above program

I am not able to understand what is the difference between the statements

int* const p=NULL;
int const *q=NULL;
halfer
  • 19,824
  • 17
  • 99
  • 186
Registered User
  • 5,173
  • 16
  • 47
  • 73
  • Possible duplicate of [What is the difference between const int\*, const int \* const, and int const \*?](http://stackoverflow.com/questions/1143262/what-is-the-difference-between-const-int-const-int-const-and-int-const) – Emil Laine Feb 14 '16 at 13:03

5 Answers5

28

int* const p=NULL;

p is a constant-pointer to an integer. The pointer IS constant (the pointer value cannot be changed); the integer pointed to is not constant (the integer value can be modified).

So statement:

p++;

will fail to compile because trying to modify a constant value (the pointer).

and statement:

(*p)++;

will increment the integer value being pointed by pointer p (but because p is assigned NULL, it will be undefined behaviour)


int const *q=NULL;

q is a pointer to a constant-integer.The pointer is not constant (the pointer value can be changed); the integer pointed to IS constant (the integer value cannot be modified).

So statement:

q++;

will modify pointer q to point to memory 4 bytes ahead (assuming sizeof(int) is 4). (because q is assigned NULL, q will be 0x4 -- I assume NULL is zero (which is true in all current implementation), incrementing NULL pointer is actually undefined behaviour )

and statement:

(*q)++;

will fail to compile because trying to modify a constant value (the integer pointed to is a constant)

dragon135
  • 1,366
  • 8
  • 19
25

How will above program behave?

This is rather simple to answer: the program will not compile.

The postfix ++ requires a modifiable lvalue as its argument; p is not modifiable because it is const-qualified.

The const after the * means that the pointer is qualified; if the const appears before the * as it does in the declaration of q, it means that the object referred to by the pointer is qualified. You can decode the C declarator syntax using the clockwise/spiral rule.


If you remove p and all references to it from the program so that only the lines containing q remain, the answer is that the program exhibits undefined behavior: you cannot perform arithmetic on a null pointer (at least not if the result is not the null pointer).

James McNellis
  • 348,265
  • 75
  • 913
  • 977
  • I read your spiral rule link but I got more confused on that link an example is `void (*signal(int, void (*fp)(int)))(int);` I am not able to understand this one and in my program as per my understanding based on your answer, p is a constant pointer i.e. p=0xf4345 some thing like this and this can not be changed.But you mention in the 2nd delcaration const *q the object referred to by q is const, is that right if yes then how is that working as per your rule? – Registered User Jun 20 '11 at 05:41
  • `p` is a pointer. Its value will always be `NULL` because it is `const`. `q` is also a pointer. Its value is `NULL` right now. You can change where `q` points because `q` itself is not `const`, you have declared `*q` as `const` (that is, the thing pointed to by `q` cannot be modified through `q`). – James McNellis Jun 20 '11 at 06:34
2

http://publications.gbdirect.co.uk/c_book/chapter8/const_and_volatile.html

They specifically say there:

An interesting extra feature pops up now. What does this mean?

char c; char *const cp = &c;

It's simple really; cp is a pointer to a char, which is exactly what it would be if the const weren't there. The const means that cp is not to be modified, although whatever it points to can be—the pointer is constant, not the thing that it points to. The other way round is

const char *cp; which means that now cp is an ordinary, modifiable pointer, but the thing that it points to must not be modified. So, depending on what you choose to do, both the pointer and the thing it points to may be modifiable or not; just choose the appropriate declaration.

Pawel Veselov
  • 3,996
  • 7
  • 44
  • 62
1

For answering this question and many more questions about const and pointers you have to understand something basic. I will explain it verbally first, and then with an example:

A pointer object can be declared as a const pointer or a pointer to a const object (or both):

A const pointer cannot be reassigned to point to a different object from the one it is initially assigned, but it can be used to modify the object that it points to (called the "pointee"). Reference variables are thus an alternate syntax for constpointers.

A pointer to a const object, on the other hand, can be reassigned to point to another object of the same type or of a convertible type, but it cannot be used to modify any object.

A const pointer to a const object can also be declared and can neither be used to modify the pointee nor be reassigned to point to another object.

Example:

void Foo( int * ptr,
         int const * ptrToConst,
         int * const constPtr,
         int const * const constPtrToConst ) 
{ 
    *ptr = 0; // OK: modifies the "pointee" data 
    ptr = 0; // OK: modifies the pointer 

    *ptrToConst = 0; // Error! Cannot modify the "pointee" data
     ptrToConst = 0; // OK: modifies the pointer 

    *constPtr = 0; // OK: modifies the "pointee" data 
    constPtr = 0; // Error! Cannot modify the pointer 

    *constPtrToConst = 0; // Error! Cannot modify the "pointee" data 
    constPtrToConst = 0; // Error! Cannot modify the pointer 
}
halfer
  • 19,824
  • 17
  • 99
  • 186
Barel
  • 71
  • 1
  • 7
0

I have just put the code provided and ran it, the enter image description here
I then compiled it,and an error of read only pointer can not be modified and in our case incremented as below abort compilationenter image description here I want just only to give an example of where we can not use const pointers.

Another example from the network simulator ns3 that clarifies constant pointer usage. when we define error model that will examine arriving packets. a function na After IsCorrupt return true(in case of error), then the program can then drop or delete the packet from its data buffer.

  bool IsCorrupt (Ptr<Packet> pkt);

Note that we do not pass a const pointer, thereby allowing the function to modify the packet if IsCorrupt() returns true.