1

Possible Duplicate:
Is there a difference in C++ between copy initialization and direct initialization?

Is there any difference between,

int x(5);
int x = 5;

& What's the difference between,

int const x(5);
const int x(5);
Community
  • 1
  • 1
Quazi Irfan
  • 2,555
  • 5
  • 34
  • 69

8 Answers8

4

Of the 4 lines you show, only 1 is valid C.

int x(5);        /* INVALID C */
int x = 5;
int const x(5);  /* INVALID C */
const int x(5);  /* INVALID C */

I don't know the meaning of the invalid lines in other languages. In C, the meaning of the valid line is to create an object with name x, type int, and value 5.


To define a "const" (better: a "read-only") object, the C syntax is

const int x = 5;
int const x = 5;

but x cannot be used in places where only constants are allowed. x is not a constant: it is an object of type const int

#define CONSTANT 42
enum /*unnamed*/ { First=1, Second, Third };
switch (var) {
    case x: break; /* invalid use of x; only constants allowed in case labels */
    case 15: break; /* ok; 15 is a constant */
    case CONSTANT: break; /* ok; CONSTANT is a constant with value 42 */
    case Second: break; /* ok; Second is a constant with value 2 */
}
pmg
  • 106,608
  • 13
  • 126
  • 198
  • is, `const int x = 5` valid in C? – Quazi Irfan Jul 05 '11 at 09:22
  • Yes, it creates an object named `x`, with value `5` and qualified type `const int`. Note the (unqualified or base) type is still `int`; it doesn't create a constant (as usuable in, for instance, case labels): it creates an object that cannot be changed through that identifier. – pmg Jul 05 '11 at 09:24
  • to make use of `case x: break;` do I have to use `const int x = 5;` ? – Quazi Irfan Jul 05 '11 at 09:40
  • 1
    @iamcreasy: no, in C the type qualifier `const` does not create a constant. It creates an object that cannot have its value changed through its defining name. **Objects** cannot be used where **constants** are expected. Use one of the other options when you need a real constant. – pmg Jul 05 '11 at 09:47
2

For the first, there's no difference for built-in types. For class types, the T x = y notation requires a copy constructor, the T x(y) notation doesn't. EDIT: Also, as one of the commenters pointed out, T x = y will not work if the T(y) constructor is declared explicit.

For the second, there's no difference as far as the compiler is concerned, but the second (const int) can lead to confusion in many cases, especially when typedefs are involved, e.g.:

typedef int* IntPtr;
IntPtr const cpi1;  //  Const pointer to a non-const int.
const IntPtr cpi2;  //  Also a const pointer to a non-const int.

In both definitions, the const applies to the pointer.

Because of this confusion, it's generally considered better practice to put the const after what it modifies. Now—for a long time, putting the const at the start was usual, with the result that the practice is widespread.

James Kanze
  • 150,581
  • 18
  • 184
  • 329
  • 1
    `const` at the start is also how it's usually written in the standard. – R. Martinho Fernandes Jul 05 '11 at 09:27
  • "For class types, the `T x = y` notation requires a copy constructor, the `T x(y)` notation doesn't." This is not so. Both require a copy constructor. `T x = y` looks like assignment but is not one. – Rafał Dowgird Jul 05 '11 at 09:42
  • @Fernandes Yes, and the standard is based on the ARM. It never seemed worth the bother changing (and there are some older programmers who are so used to `const int` they wouldn't feel comfortable if we did change). The "generally accepted" best practice has changed to favor `int const`, but not to the point where you'd be criticized for using `const int`, or where it would be worth changing the practice in existing code. – James Kanze Jul 05 '11 at 09:51
  • @Rafal `T x(y)` does not require a copy constructor. It requires a constructor which can be invoked with whatever type `y` has. `T x = y` requires an accessible copy constructor. (And nobody said anything about assignment.) – James Kanze Jul 05 '11 at 09:52
  • @James It's good to know about this recommendation. I think I'll be more careful in the future :) Also, you may want to mention that T x = y; will not work if a call to an explicit constructor would be involved. – R. Martinho Fernandes Jul 05 '11 at 09:58
  • @James: You are correct, I typed my comment before realizing that y need not be the same type as x. – Rafał Dowgird Jul 05 '11 at 10:01
  • @Martinho Good point concerning the explicit constructor. That's likely to affect as much code as the need for a copy constructor. – James Kanze Jul 05 '11 at 10:10
2

A really good rule of thumb regarding const:

Read Declarations Right-to-Left.

(see Vandevoorde/Josutiss "C++ Templates: The Complete Guide")

E.g.:

int const x; // x is a constant int
const int x; // x is an int which is const

// easy. the rule becomes really useful in the following:
int const * const p; // p is const-pointer to const-int
int const &p;        // p is a reference to const-int
int * const * p;     // p is a pointer to const-pointer to int.

Ever since I follow this rule-of-thumb, I never misinterpreted such declarations again.

(: sisab retcarahc-rep a no ton ,sisab nekot-rep a no tfel-ot-thgir naem I hguohT :tidE

Sebastian Mach
  • 38,570
  • 8
  • 95
  • 130
1

No both are exactly same until you are using an Argument. It's just a matter of coding style.

[Note: But Following are not same:

int x;  // x is variable
int x();  // x is function declaration

]

iammilind
  • 68,093
  • 33
  • 169
  • 336
1

About the const keyword:

  • It makes const what is immediately to its left
  • If there is nothing to the left, then it applies to the right.

So, int const i and const int i are the same.

But, int *const i and const int *i are not the same: in the first expression, the pointer is constant, in the second expression, the integer pointed to is constant. Als int const* i is equivalent to the second one.

Benoit
  • 76,634
  • 23
  • 210
  • 236
  • * character, which side does it work first? Left or right? – Quazi Irfan Jul 05 '11 at 09:28
  • `*` either follows a **type name**: in this case it is a type modifier (modifies the type to a pointer type), or follows an **expression**: in this case it is the multiplication operator, or precedes an expression that is bound to a pointer type: it is the **dereference** operator. There is no such rule. – Benoit Jul 05 '11 at 09:43
  • `int *const i` : i is a const pointer, which point a non-const int & `int const* i` : i is a pointer which, points to an const int. It is correct? – Quazi Irfan Jul 05 '11 at 11:29
  • @iamcreasy: yes. That's what many people tell here! – Benoit Jul 05 '11 at 11:33
0

No difference. Alternate ways to initialize the variable to a value.

But did you try this on your system? What did you get?

Sriram
  • 10,298
  • 21
  • 83
  • 136
0

There's no difference in c++, in c, however - int x(5); is not allowed

MByD
  • 135,866
  • 28
  • 264
  • 277
-1
int x(5);
int x = 5;

No difference.

int const x(5);
const int x(5);

No difference.

int x = 5;
const int *p = &x;
int *const q = &x;

Here is a difference in p and q. Using p you can't change the value of x, but you can assign a new address to p. Using q, you cannot point to any other memory location, but you can modify x using q.

Donotalo
  • 12,748
  • 25
  • 83
  • 121