At least in my reading of N3337, gcc is correct, and MSVC is incorrect (unless you disable its extensions).
The path begins with Β§ 4 of the standard:
Standard conversions are implicit conversions with a built-in value. Clause 4 lists the complete set of such transformations.
Thus, the only standard transformations that exist are those listed in section 4. However, not all possible standard transformations can be applied in every situation. Only those that fit together in a standard conversion sequence can be used. The standard conversion sequence is defined as follows:
- Zero or one conversion from the following set: conversion of lvalue-to-rval, conversion between arrays and pointers and conversion of a function to a pointer.
- Zero or one conversion from the following set: integral promotions, floating point promotion, integral conversions, floating point conversions, floating integral conversions, pointer conversions, pointers to member conversions, and logical conversions.
- Zero or one qualification conversion.
Here we start with a pointer to a function, so conversions below the first marker point cannot be applied. We do not need / care about the transition to qualifications, so we do not care about the third point.
For conversion from pointer to function to pointer to void will be a pointer conversion explicitly. They are presented in exactly three versions. In Β§ 4.10 / 1, we have pointer conversions starting with the null pointer constants (which is not explicitly applied here). Β§4.10 / 2 deals with transformations starting with:
Value of type "pointer to cv T", where T is the type of object [...]
This is not explicitly applied here because the function is not an object. The third option:
The value of the class "pointer to cv D", where D is the type of class [...]
Again, the function is not a type of class, so it also cannot be used.
This leaves us with only one option: one conversion directly from "pointer to function" to "Boolean". These, of course, are Boolean transformations. Β§4.12 states:
The value of arithmetic, an enumerated enumeration, a pointer, or a pointer to a member type can be converted to a prvalue of type bool.
So, our value can be converted to Boolean if and only if 1) it is prvalue, and 2) is a pointer. This probably seems pretty obvious, but if we want to confirm, we can look at the definition of the address of the operator in Β§5.3.1 / 2 and 5.3.1 / 3:
The result of each of the following unary operators is a prvalue.
This meets the first requirement.
The result of the unary and operator is a pointer to its operand. The operand must be lvalue or identified-id. If the operand is a qualified identifier that names the non-static member m of some class C with type T, the result is of type "pointer to a member of class C of type T" and is the character assignment C :: m. Otherwise, if the type of the expression is T, the result is of type βpointer to Tβ and is a prvalue, which is the address of the specified object (1.7) or a pointer to the assigned function. [highlighted by me]
This clearly fulfills the second requirement - the result is a pointer.
Since these requirements are met, conversion can / will happen. The conversion result is as follows (back to Β§4.12):
A null value, a null pointer value, or a null element pointer value is converted to false; any other value is converted to true.
Since we started with a pointer to the actual function, we cannot have a null pointer. This leaves only one possibility: "any other value is converted to true."
Just like a warning from gcc says, the only possible conversion result is a boolean with a value of true . This will display as β1β by default, or βtrueβ if boolalpha set to true.