tags:

views:

3415

answers:

8
+11  Q: 

Const in C

Quick question:

int testfunc1 (const int a)
{
  return a;
}

int testfunc2 (int const a)
{
  return a;
}

Are these two functions the same in every aspect or is there a difference? I'm interested in an answer for the C-language, but if there is something interested in the C++ case I'd like to know as well.

+1  A: 

Yes, they are same for just int

and different for int*

Prakash
(const int *) and (int const *) are the same, they are just different from (int *const).
James Antill
+27  A: 

const T and T const are identical. Pay attention to pointer precedence, however:

char const* is a pointer to a constant char (array), while char* const is a constant pointer to a mutable char (array).

Konrad Rudolph
C does have const, given: static const char foo[] = "foo"; you better not alter foo.
James Antill
K C90 (and C99) does. It's a bit limited compared to C++, but it is useful.
Mark Baker
I've already removed that nonsense from my text. ;-)
Konrad Rudolph
+1  A: 

I think in this case they are the same, but here is an example where order matters:

const int* cantChangeTheData;
int* const cantChangeTheAddress;
Tim Sally
Indeed, but int const * is the same as the first, so the order of the int and const doesn't matter, it's just the order of the * and the const that does.
Mark Baker
+1  A: 

Prakash is correct that the declarations are the same, although a little more explanation of the pointer case might be in order.

"const int* p" is a pointer to an int that does not allow the int to be changed through that pointer. "int* const p" is a pointer to an int that cannot be changed to point to another int.

See http://www.parashift.com/c++-faq-lite/const-correctness.html#faq-18.5.

Fred Larson
+2  A: 

There is no difference. They both declare "a" to be an integer that cannot be changed.

The place where differences start to appear is when you use pointers.

Both of these:

const int *a
int const *a

declare "a" to be a pointer to an integer that doesn't change. "a" can be assigned to, but "*a" cannot.

int * const a

declares "a" to be a constant pointer to an integer. "*a" can be assigned to, but "a" cannot.

const int * const a

declares "a" to be a constant pointer to a constant integer. Neither "a" nor "*a" can be assigned to.

static int one = 1;

int testfunc3 (const int *a)
{
  *a = 1; /* Error */
  a = &one;
  return *a;
}

int testfunc4 (int * const a)
{
  *a = 1;
  a = &one; /* Error */
  return *a;
}

int testfunc5 (const int * const a)
{
  *a = 1;   /* Error */
  a = &one; /* Error */
  return *a;
}
Glomek
+14  A: 

The trick is to read the declaration backwards (right-to-left):

const int a = 1; // read as "a is an integer which is constant"
int const a = 1; // read as "a is a constant integer"

Both are the same thing. Therefore:

a = 2; // Can't do because a is constant

The reading backwards trick especially comes in handy when you're dealing with more complex declarations such as:

const char *s;      // read as "s is a pointer to a char that is constant"
char c;
char *const t = &c; // read as "t is a constant pointer to a char"

*s = 'A'; // Can't do because the char is constant
s++;      // Can do because the pointer isn't constant
*t = 'A'; // Can do because the char isn't constant
t++;      // Can't do because the pointer is constant
Ates Goral
I like the backward reading trick. :-)
Alan Haggai Alavi
A: 

This isn't a direct answer but a related tip. To keep things straight, I always use the convection "put const on the outside", where by "outside" I mean the far left or far right. That way there is no confusion -- the const applies to the closest thing (either the type or the *). E.g.,



int * const foo = ...; // Pointer cannot change, pointed to value can change
const int * bar = ...; // Pointer can change, pointed to value cannot change
int * baz = ...; // Pointer can change, pointed to value can change
const int * const qux = ...; // Pointer cannot change, pointed to value cannot change
Pat Notz
+1  A: 

const int is identical to int const, as is true with all scalar types in C. In general, declaring a scalar function parameter as const is not needed, since C's call-by-value semantics mean that any changes to the variable are local to its enclosing function.

Emerick Rogul