问题
This is a continuation of my answer to why is elapsedtime giving me an output of 1?
I was able to successfully compile and build the following program using g++ 4.7.3.
#include <iostream>
using namespace std;
int elapsedtime(int time1, int time2)
{
return (time2-time1);
}
int main()
{
int time1;
int time2;
cin >> time1 >> time2;
cout << "Your elapsed time is " << elapsedtime <<endl;
}
The intent of the last line in main
is:
cout << "Your elapsed time is " << elapsedtime(time1, time2) <<endl;
How is g++ able to compile the first version without error?
回答1:
std::ostream
has an operator << (bool)
, and function names are implicitly convertible to bool
under the standard (by a function-to-pointer conversion followed by a boolean conversion). The relevant language is (§4 [conv]/p1, §4.3 [conv.func], §4.12 [conv.bool]) :
A standard conversion sequence is a sequence of standard conversions in the following order:
- Zero or one conversion from the following set: lvalue-to-rvalue conversion, array-to-pointer conversion, and function-to-pointer conversion.
- Zero or one conversion from the following set: integral promotions, floating point promotion, integral conversions, floating point conversions, floating-integral conversions, pointer conversions, pointer to member conversions, and boolean conversions.
- Zero or one qualification conversion.
An lvalue of function type T can be converted to a prvalue of type "pointer to T." The result is a pointer to the function.
A prvalue of arithmetic, unscoped enumeration, pointer, or pointer to member type can be converted to a prvalue of type
bool
. A zero value, null pointer value, or null member pointer value is converted tofalse
; any other value is converted totrue
.
回答2:
With proper warning levels, GCC will warn:
test.cpp|14 col 39| warning: the address of 'int elapsedtime(int, int)' will always evaluate as 'true' [-Waddress]
See it GCC 4.7 On Coliru and clang too
回答3:
Because it is completely valid C++.
A function name is implicitly convertible to a pointer to that function.
For MSVC, the standard library provides a output operator for arbitrary pointers that prints the numerical value of that pointer.
For GCC/Clang the result is a bit complicated: They (correctly) do not implement an inserter that matches function pointers. Instead the function pointer is implicitly converted to bool which is true (1), since the pointer is not null. The conversion sequence can also be written explicitly like this.
int(*p)(int, int) = elapsedtime;
bool b = p;
cout << "Your elapsed time is " << b <<endl;
Note that with the proper warning level, both g++ and clang will warn you when an implicit conversion sequence causes a function name to be evaluated to true
with a warning similar to:
warning: address of function 'elapsedtime' will always evaluate to 'true' [-Wbool-conversion]
来源:https://stackoverflow.com/questions/23530206/how-does-g-not-report-error-with-the-given-code