2
votes

Clang 3.0 rejects the following code, complaining that g(unsigned long) was not found. GCC 4.8 accepts it without error.

void g(int*);

void f()
{
    g(sizeof(int) - sizeof(int)); // ok, evaluates to 0
}

template<typename T>
struct A
{
    void f()
    {
        g(sizeof(T) - sizeof(T)); // error: no matching function
    }
};

My reading of the standard suggests that 'g' is not a dependent name, and should be looked up and bound immediately as clang seems to do. Even so, the behaviour specified by the standard seems wrong, because g would otherwise be bound correctly at instantiation time.

[temp.dep]
[...] In an expression of the form:
postfix-expression ( expression-listopt)
where the postfix-expression is an id-expression, the id-expression denotes a dependent name if any of the expressions in the expression-list is a type-dependent expression (14.6.2.2) or if the unqualified-id of the id-expression is a template-id in which any of the template arguments depends on a template parameter. If an operand of an operator is a type-dependent expression, the operator also denotes a dependent name. Such names are unbound and are looked up at the point of the template instantiation (14.6.4.1) in both the context of the template definition and the context of the point of instantiation.

What is the compliant behaviour in this scenario?

1

1 Answers

1
votes

Turns out that this behaviour is unspecified due to a known defect in the C++ standard:

http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html

DR 903. Value-dependent integral null pointer constants

The proposed resolution is to change the wording of the standard to allow only the literal '0' as a null pointer constant, but this is under review as it would mean breaking existing code that uses 'false'.

GCC appears to resolve this by treating 'g' as a dependent name. In contrast, Clang appears to rule that a value-dependent expression can never be a null pointer constant expression. Neither approach is strictly correct, because the correct behaviour is unspecified.