This is an unofficial snapshot of the ISO/IEC JTC1 SC22 WG21 Core Issues List revision 115e. See http://www.open-std.org/jtc1/sc22/wg21/ for the official list.
2024-11-11
[Moved to DR status at the April, 2013 meeting.]
Consider the following example:
void f(int*); void f(...); template <int N> void g() { f(N); } int main() { g<0>(); g<1>(); }
The call to f in g is not type-dependent, so the overload resolution must be done at definition time rather than at instantiation time. As a result, both of the calls to g will result in calls to f(...), i.e., N will not be a null pointer constant, even if the value of N is 0.
It would be most consistent to adopt a rule that a value-dependent expression can never be a null pointer constant, even in cases like
template <int N> void g() { int* p = N; }
This would always be ill-formed, even when N is 0.
John Spicer: It's clear that this treatment is required for overload resolution, but it seems too expansive given that there are other cases in which the value of a template parameter can affect the validity of the program, and an implementation is forbidden to issue a diagnostic on a template definition unless there are no possible valid specializations.
Notes from the July, 2009 meeting:
There was a strong consensus among the CWG that only the literal 0 should be considered a null pointer constant, not any arbitrary zero-valued constant expression as is currently specified.
Proposed resolution (October, 2012):
Change 7.3.12 [conv.ptr] paragraph 1 as follows:
A null pointer constant is anintegral constant expression (7.7 [expr.const]) prvalue of integer type that evaluates tointeger literal (5.13.2 [lex.icon]) with value zero or a prvalue of type std::nullptr_t. A null pointer constant can be converted...
Change 7.7 [expr.const] paragraph 3 as follows:
...[Note: Such expressions may be used as array bounds (9.3.4.5 [dcl.array], 7.6.2.8 [expr.new]), as bit-field lengths (11.4.10 [class.bit]), as enumerator initializers if the underlying type is not fixed (9.7.1 [dcl.enum]),as null pointer constants (7.3.12 [conv.ptr]),and as alignments (9.12.2 [dcl.align]). —end note]...
Change 9.4 [dcl.init] paragraph 5 as follows:
To zero-initialize an object or reference of type T means:
if T is a scalar type (6.8 [basic.types]), the object is
set to the value 0 (zero), taken as an integral constant expression, convertedinitialized to the value obtained by converting integer literal 0 (zero) to T; [Footnote: As specified in 7.3.12 [conv.ptr], converting anintegral constant expressioninteger literal whose value is 0 to a pointer type results in a null pointer value. —end footnote]...
Change 13.4.3 [temp.arg.nontype] paragraph 5 as follows:
...
for a non-type template-parameter of type pointer to
object, qualification conversions (7.3.6 [conv.qual]) and the
array-to-pointer conversion (7.3.3 [conv.array]) are applied; if
the template-argument is of type std::nullptr_t, the
null pointer conversion (7.3.12 [conv.ptr]) is applied.
[Note: In particular, neither the null pointer conversion for a
zero-valued integral constant expression integer
literal (7.3.12 [conv.ptr]) nor the derived-to-base
conversion (7.3.12 [conv.ptr]) are applied. Although 0
is...
...
Change 14.4 [except.handle] paragraph 3 as follows:
...[Note: A throw-expression whose operand is anintegral constant expression of integer type that evaluates tointeger literal with value zero does not match a handler of pointer or pointer to member type. —end note]. [Example: ...
Add a new section to C.6 [diff.cpp03] as follows:
C.2.x Clause 4: standard conversions [diff.cpp03.conv] 7.3.12 [conv.ptr]
Change: Only literals are integer null pointer constants
Rationale: Removing surprising interactions with templates and constant expressions
Effect on original feature: Valid C++ 2003 code may fail to compile or produce different results in this International Standard, as the following example illustrates:
void f(void *); // #1 void f(...); // #2 template<int N> void g() { f(0*N); // calls #2; used to call #1 }
Additional note (January, 2013):
Concerns were raised at the Portland (October, 2012) meeting that the value false has been used in existing code as a null pointer constant, and such code would be broken by this change. This issue has been returned to "review" status to allow discussion of whether to accommodate such code or not.