Search code examples
c++iteratordefault-constructor

iterator default constructor and POD member initialization


From an example [1] in the documentation for boost::iterator_facade:

class node_iterator : public boost::iterator_facade< /* ... */ >
{
 public:  node_iterator() : m_node(0) { } 
          /* ... */
 private: node_base* m_node;
};

Followed by a footnote:

Technically, the C++ standard places almost no requirements on a default-constructed iterator, so if we were really concerned with efficiency, we could've written the default constructor to leave m_node uninitialized.

My question (two parts):
(a) What requirements does the C++ standard place on a default-constructed iterator?
(b) Why would leaving out m_node(0) avoid initializing m_node when instantiating a node_iterator? Wouldn't m_node then be default-initialized (thus zero-initialized) anyway?

[1] http://www.boost.org/doc/libs/1_47_0/libs/iterator/doc/iterator_facade.html#constructors-and-data-members (nb: Although this question originated from a boost example, I believe it applies to STL iterators, thus I did not use a "boost" tag.)


Solution

  • Why would leaving out m_node(0) avoid initializing m_node when instantiating a node_iterator?

    Just because the default constructor for a node_iterator is called does not mean that the non-static data-members of the class itself are properly initialized, especially if no initialization is specified for those data-members. This includes omitting those non-static data-members from the constructor initialization list. Furthermore, m_node is a pointer, and therefore a POD-type, thus it does not have a default-constructor that would be called to construct the object before entering the body of the constructor for node_iterator itself. Therefore omitting m_node from the initializer list would avoid specifically initializing the m_node data_member.

    Wouldn't m_node then be default-initialized (thus zero-initialized) anyway?

    Per the C++03 spec, section 8.5/9, a non-static object (which also includes a non-static data-member of a class) is initialized with an "indeterminant" value if no initializer is specified for that object. A non-static object is only default-initialized if it is a non-POD class type and/or a const-qualified type. In this case m_node is a pointer-type, and is therefore a POD-type, so it is not zero-initialized ... it's just "initialized" with whatever pre-existing value was in memory at the location of the variable, thus making it an "indeterminant" value that it's initialized with.