52

After reading this article I made a point that int () yields 0 because the temporary int is value initialized and not because int() calls the default constructor for int. (The article is flawed according to my understanding.)

I also said that primitive (built-in) types don't have constructors. The original author asked me to check Section $10.4.2 (TC++PL) which says

Built-in types also have default constructors ($6.2.8)

But I still think that the statement "C++ allows even built-in type (primitive types) to have default constructors." is flawed (as per C++03).

I think Bjarne in TC++PL has mixed up "constructor like notation i.e ()" with actual constructor call. Value initialization was not introduced at that time when Bjarne was writing the book, right? So is the text in TC++PL incorrect as per C++98 and C++03?

What do you guys think?

EDIT

I asked Bjarne personally (via mail) regarding the flawed text in TC++PL and this was his reply

I think you mix up "actual constructor calls" with conceptually having a constructor. Built-in types are considered to have constructors (whatever words the standard uses to describe their behavior).

RBZ
  • 2,034
  • 17
  • 34
Prasoon Saurav
  • 91,295
  • 49
  • 239
  • 345
  • 13
    Why is this being closed as subjective and argumentative? This has got a "Yes/No" answer for sure. – Prasoon Saurav Feb 25 '11 at 03:47
  • I think this contradiction has come up on SO before, by the way. TC++PL simplifies and generalizes things a bit too much in some areas, and is wrong in this case. – GManNickG Feb 25 '11 at 03:51
  • If it looks like a constructor and walks like a constructor and talks like a constructor... does it really matter if it isn't a constructor? – user541686 Feb 25 '11 at 03:57
  • Sounds like an argument over terminology to me. – Steve Feb 25 '11 at 04:07
  • So the follow up point is: what is this thing `int()`? As far I can see it is an example of an initializer which in this case results in default initialization. – Keith Feb 25 '11 at 05:13
  • @Keith : `()` implies value initialization in this context. [Default initialization is different from value initialization](http://stackoverflow.com/questions/620137/do-the-parentheses-after-the-type-name-make-a-difference-with-new/620402#620402). – Prasoon Saurav Feb 25 '11 at 05:14
  • @Prasoon. Thanks. Was reading C++98, 8.5/7: "An object whose initializer is an empty set of parentheses, i.e., (), shall be default initialized". Now understand that C++03 changed it. – Keith Feb 25 '11 at 05:18
  • 2
    @Keith : Value initialization was introduced in C++03. Section 8.5/5. "An object whose initializer is an empty set of parentheses, i.e., (), shall be value-initialized." – Prasoon Saurav Feb 25 '11 at 05:19
  • @PrasoonSaurav: you are wrong. Primitive types have constructors. visit & read this: http://www.informit.com/guides/content.aspx?g=cplusplus&seqNum=15. & yes, if you think that u r right then something like int i=int(); should print a garbage value in C++98 not 0 as a value of variable i. How can you say that creator of C++ & his book content is wrong? – Destructor May 09 '15 at 13:08
  • It doesn't walk like a constructor. For example, `int x({0})` is not allowed. Brace initialization has different rules for scalars because there is no constructor resolution for them. – memeplex Jan 28 '16 at 05:46
  • Unfortunately Bjarne's answer indicates that he's out of touch with this set of conceptual models used in standard C++. No, built-in types do not have constructors, neither actual nor conceptual. In C++ only class types are considered to have constructors (conceptual or not). Bjarne's answer is incorrect. – AnT stands with Russia Aug 03 '18 at 21:52
  • @Destructor: "How can you say that creator of C++ & his book content is wrong?". Because Stroustrup is patently is wrong in this case. This error has been present in his book for quite a while. It is a well-known error. It is usually assumed that the error is intentional, made for the purpose of simplifying the text. But if the above quote from his email response is correct, then apparently Bjarne is genuinely confused about this part of language specification. – AnT stands with Russia Aug 03 '18 at 21:55

3 Answers3

55

Simple Answer: Technically No.

Long Answer:

No. But!

The syntax you use to initialize them makes them look like they are being constructed by a default constructor or a default copy constructor.

int x0(5);     // Looks like a constructor. Behaves like one: x is initialized.
int x1{5};

int y0();      // Fail. Actually a function declaration.
// BUT
int y1{};      // So new syntax to allow for zero initialization
int z0 = int();// Looks like a constructor. Behaves like a constructor (0 init).
int z1 = int{};

int a0(b);     // Again.
int a1{b};

So technically there are no constructors for basic-POD types. But for all intents and purposes they act just like they have a copy constructor and default constructor (when initialized with the braces).

If it looks like a duck and quacks like a duck, then its very duck like.

Martin York
  • 257,169
  • 86
  • 333
  • 562
  • 1
    so the syntax like : `int x(5);` gets converted to `int x; x=5;` ? thanks :) – Mr.Anubis May 21 '12 at 20:32
  • 7
    @SoulReaper: Not quote. `int x(5);` is equivalent to `int x = 5`. Though after compilation I doubt you will see any difference in the object from any of these. – Martin York May 21 '12 at 20:42
  • @LokiAstari To me the `int()` is the most perplexing. If not a constructor what even is that? – Jonathan Mee Dec 11 '14 at 12:03
  • 5
    @JonathanMee: It forces zero initialization rather than default initialization (I forget the exact name of the technique). If you think of a user defined type `T` with a compiler defined constructors. Then `T x;T* y = new T;` is default initialization `T x = T();T* y = new T()` is zero initialization. It was designed so that templates would work the same with user-defined types and POD types. – Martin York Dec 11 '14 at 18:50
  • 1
    @LokiAstari If you're interested, I asked for the, "name of the technique" here: http://stackoverflow.com/q/27443532/2642059 – Jonathan Mee Dec 12 '14 at 12:55
  • @LokiAstari: But http://www.informit.com/guides/content.aspx?g=cplusplus&seqNum=15 says that built in types have constructors. Also, The C++ programming language by Stroustrup also says that primitive types have ctors. so, what's the final conclusion means ur opinion? – Destructor May 08 '15 at 16:51
  • @meet: `informit` is simplifying the topic for beginners and saying exactly what I said above. It looks like a constructor and behaves like a constructor you may as well think of it as a constructor. You will have to show my Stroustrups exact words. But in the strict sense of the word a constructor is a method of a class and that's how you will find it defined in the actually standard (see clause 12) . But. If it looks like a duck and quacks like a duck then you can use it like a duck. See James McNallis above. – Martin York May 08 '15 at 19:29
  • It doesn't quacks like a constructor. For example, `int x({0})` is not allowed. Brace initialization has different rules for scalars because there is no constructor resolution for them. – memeplex Jan 28 '16 at 05:54
  • @memeplex: `int x{0};` and `int x{}` work as expected. Which is the way I would expect you to write them. I have not idea why you are using both '()' and '{}' in the same expression. The point of that addition of '{}' was as an alternative to avoid situations where the syntax was confusing (ie complex for the compiler). – Martin York Jan 28 '16 at 18:35
  • Sure, albeit my point is that ({0}) will work for real constructors that do overload resolution but will not work for basic types which share the parenthetical syntax but not much more. – memeplex Jan 29 '16 at 03:10
  • My point is simpler than you think: A({1}) will work for class A with constructor A(int x) because {1} will initialize x after this constructor was selected. But int({1}) will not work, because this is not brace initializing some first argument of some int constructor, int{1} is the right choice as we both know. This clearly follows from the initialization rules in the iso standard. My intention was to provide an example in which proper constructor behavior diverges from syntactically similar constructs for basic types. – memeplex Jan 29 '16 at 03:27
  • And yes, A({1}) works for class types. First, check it in your compiler. Then check the initialization rules: it will skip the brace initialization at first, but then the A(int x) constructor will be selected because {1} can brace initialize x, all this assuming A is not implementing an initializer list constructor. – memeplex Jan 29 '16 at 03:32
  • Oops got that wrong. You just show that using weird syntax does not work everywhere. nothing else. – Martin York Jan 29 '16 at 03:45
  • The duck quote at the end is an actually thing in CS https://en.wikipedia.org/wiki/Duck_typing – interesting Sep 29 '22 at 11:54
32

A constructor is a member function (constructors are fully specified in clause 12 of the C++ Standard, which covers special member functions like constructors and destructors).

A member function can only be defined for a class type (C++03 9.3/1 says "Functions declared in the definition of a class, excluding those declared with a friend specifier, are called member functions of that class").

So non-class types (including fundamental types, array types, reference types, pointer types, and enum types) do not have constructors.

I don't have a copy of The C++ Programming Language to read the context of the quote that "Built-in types also have default constructors," but I would guess that Stroustrup is either using the term "constructor" in a loose, non-technical sense, or the meaning of the term or the way in which it is used in the Standard changed between when the book was published and when the language was standardized. I'd guess the former is far more likely than the latter.

James McNellis
  • 348,265
  • 75
  • 913
  • 977
5

As others have pointed out, the Standard contradicts TC++PL in a few instances, often related to terminology. Bjarne Stroustrup himself summarizes the situation well:

(...) However, [TC++PL] is not a reference manual or the standards text. If you need 100% precise and complete information you'll have to consult the text of the ISO C++ standard. (...)

Neilana
  • 104
  • 1
  • 6
decltype
  • 1,591
  • 8
  • 12