41

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

I just started to learn C++.

To initialize a variable with a value, I came across

int a = 0;

and

int a(0);

This confuses me a lot. May I know which is the best way?

Community
  • 1
  • 1
Psycho Donut
  • 273
  • 1
  • 3
  • 10

7 Answers7

64

int a = 0; and int a(0); make no difference in the machine generated code. They are the same.

Following is the assembly code generated in Visual Studio

int a = 10;   // mov dword ptr [a],0Ah  
int b(10);    // mov dword ptr [b],0Ah  
Rody Oldenhuis
  • 37,726
  • 7
  • 50
  • 96
SeeJay
  • 576
  • 4
  • 5
  • 14
    I love the example shown in assembly code. – Psycho Donut Dec 06 '12 at 07:58
  • 22
    However, just because the generated code is the same, it does not mean that the language features are the same. Trying to learn the language by Black Box methods, as in "running the programs" and/or "inspecting the assembly" usually leads to massive misconceptions. – AnT stands with Russia Dec 06 '12 at 08:15
  • @SeeJay what machine code does `char c = 10;` generate? I'm curious whether `char` and `int` are the same... – Luchian Grigore Dec 06 '12 at 08:21
  • 1
    @LuchianGrigore I've just tested it's `move byte ptr [c], 0Ah` In case of `8 bits it's byte`, `16 bit => word`, `32 bit => dword`, `64 bit => qword`. – SeeJay Dec 06 '12 at 08:26
  • What about an `unsigned int`? (maybe I gave the wrong example initially, the point is the machine code proves **nothing**) – Luchian Grigore Dec 06 '12 at 08:27
  • @AndreyT yes you are right, in high level the concept can mean different thing. I'm aware that in Class Type and Primitive type, they are different. Sometimes I prefer to understand it in low level way, such by using assembly code or intermediate code. – SeeJay Dec 06 '12 at 08:29
  • 1
    For a more in detail explanation see http://stackoverflow.com/questions/1051379/is-there-a-difference-in-c-between-copy-initialization-and-direct-initializati – Micha Wiedenmann Dec 06 '12 at 11:31
23

They're both the same, so there really is no one "best way".

I personally use

int a = 0;

because I find it more clear and it's more widely used in practice.

This applies to your code, where the type is int. For class-types, the first is copy-initialization, whereas the other is direct-initialization, so in that case it would make a difference.

Luchian Grigore
  • 253,575
  • 64
  • 457
  • 625
  • 2
    For class types B b(a); and B b = a; actually are same and both use copy constructor to initialize. So there's no different. B b; b=a; use assign operator and then you have completely other case. – Dainius Dec 06 '12 at 08:35
  • 3
    @Dainius nope, they are not. – Luchian Grigore Dec 06 '12 at 08:37
  • 2
    @Dainius see http://stackoverflow.com/questions/11222076/why-is-copy-constructor-called-instead-of-conversion-constructor – Luchian Grigore Dec 06 '12 at 08:38
  • @LuchianGrigore: You are beast in `C++`. You answers are `very clear` and `to the point`. Thanks for all the good work you are doing. – Rasmi Ranjan Nayak Dec 06 '12 at 08:39
  • #include class A { public: A() {}; }; class B { public: B() { std::cout << "B ctr\n"; } B(const A&) { std::cout << "B ctr with a\n"; } B& operator = (const A&) { std::cout << "B operator = with A\n"; return *this; } }; int main(void) { A a; B b1(a); B b2 = a; return 0; } // output is B ctr with a for both calls, how it's not same? – Dainius Dec 06 '12 at 09:50
  • from http://en.wikipedia.org/wiki/Copy_constructor "X b = a; // valid if any of the copy constructors are defined" – Dainius Dec 06 '12 at 09:52
  • looks like it depends on compilator, so probably it's possible that some still creates temporary objects and not direct call for copy constructor. – Dainius Dec 06 '12 at 10:05
  • @Dainius: Where is the copy constructor you promised? Firstly, `B(const A&)` is *not* a copy constructor. Yet you said initially that "both use copy constructor". Your example contradicts your own statements. Secondly, the difference between `A a; B b(a);` and `A a; B b = a` is that the later actually does use `B`'s copy constructor (unless it gets optimized away), while the former doesn't. – AnT stands with Russia Dec 06 '12 at 15:08
5

There's no "best" way. For scalar types (like int in your example) both forms have exactly the same effect.

The int a(0) syntax for non-class types was introduced to support uniform direct-initialization syntax for class and non-class types, which is very useful in type-independent (template) code.

In non-template code the int a(0) is not needed. It is completely up to you whether you want to use the int a(0) syntax, or prefer to stick to more traditional int a = 0 syntax. Both do the same thing. The latter is more readable, in my opinion.

AnT stands with Russia
  • 312,472
  • 42
  • 525
  • 765
5

From a practical point of view: I would only use int a = 0;.

The int a(0) may be allowed but never used in practice in itself.


I think it should not bother you on your level, but let us go further.

Let's say that a is a class, not an int.

class Demo{
public:
  Demo(){}; 
  Demo(int){};
};
Demo a;
Demo b(a);   
Demo c = a;  // clearly expressing copy-init

In this example both b(a) and c=a do the same, and I would discourage you using the fist solution. My reason is, that is looks similar to c(2) which is a construction from arguments.

There are only two valid uses of this bracket-style initialization:

  • initialization lists (Demo(int i):data(i){} if Demo has an int data member data),
  • new's: Demo *p=new Demo(a); // copy constructing a pointer
Barney Szabolcs
  • 11,846
  • 12
  • 66
  • 91
2

It’s that simple. (Well, almost — there are a few things you can’t name your variables, which we’ll talk about in the next section)

You can also assign values to your variables upon declaration. When we assign values to a variable using the assignment operator (equals sign), it’s called an explicit assignment:

int a= 5; // explicit assignment

You can also assign values to variables using an implicit assignment:

int a(5); // implicit assignment

Even though implicit assignments look a lot like function calls, the compiler keeps track of which names are variables and which are functions so that they can be resolved properly.

RaJeSh
  • 313
  • 3
  • 14
  • 12
    It is *not* called assignment. *Assignment* is a reserved term in C++ terminology with a strictly defined and very specific meaning. Referring to *initialization* as "assignment" will only create unnecessary confusion. The proper terms for this two forms of initialization syntax are *direct-initialization* and *copy-initialization*. – AnT stands with Russia Dec 06 '12 at 07:48
  • class A { public: A(int) {} }; class B { public: B(const A&) {}}; B b1(10); B b2 = 20; // compiles and run. If need explicit then it should be said in declaration like explicit A(int) {} – Dainius Dec 06 '12 at 08:40
0

In textbooks and literature, one is direct initialization and the other is copy initialization. But, in terms of machine code, there is no difference.

psteelk
  • 1,305
  • 3
  • 16
  • 24
-1

The difference is that () initialization is when you explicitly want it to take one parameter only, e.g:

You can:
int a = 44 + 2;
but you can't:
int a(44) + 2;