1234. "Do the right thing" and NULL

Section: 26.2.3 [sequence.reqmts] Status: C++11 Submitter: Matt Austern Opened: 2009-10-09 Last modified: 2016-02-10

Priority: Not Prioritized

View other active issues in [sequence.reqmts].

View all other issues in [sequence.reqmts].

View all issues with C++11 status.


On g++ 4.2.4 (x86_64-linux-gnu), the following file gives a compile error:

#include <vector>
void foo() { std::vector<int*> v(500L, NULL); }

Is this supposed to work?

The issue: if NULL happens to be defined as 0L, this is an invocation of the constructor with two arguments of the same integral type. 26.2.3 [sequence.reqmts]/14 (N3035) says that this will behave as if the overloaded constructor

X(size_type, const value_type& = value_type(),
  const allocator_type& = allocator_type())

were called instead, with the arguments static_cast<size_type>(first), last and alloc, respectively. However, it does not say whether this actually means invoking that constructor with the exact textual form of the arguments as supplied by the user, or whether the standard permits an implementation to invoke that constructor with variables of the same type and value as what the user passed in. In most cases this is a distinction without a difference. In this particular case it does make a difference, since one of those things is a null pointer constant and the other is not.

Note that an implementation based on forwarding functions will use the latter interpretation.

[ 2010 Pittsburgh: Moved to Open. ]

[ 2010-03-19 Daniel provides wording. ]

This issue can be considered as a refinement of 438.

[ Post-Rapperswil ]

Wording was verified to match with the most recent WP. Jonathan Wakely and Alberto Barbati observed that the current WP has a defect that should be fixed here as well: The functions signatures fx1 and fx3 are incorrectly referring to iterator instead of const_iterator.

Moved to Tentatively Ready with revised wording after 7 positive votes on c++std-lib.

[ Adopted at 2010-11 Batavia ]

Proposed resolution:

Change 23.2.3 [sequence.reqmts]/14+15 as indicated:

14 For every sequence container defined in this Clause and in Clause 21:

15 In the previous paragraph the alternative binding will fail if first is not implicitly convertible to X::size_type or if last is not implicitly convertible to X::value_type.