Question

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?

Was it helpful?

Solution 3

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 to false; any other value is converted to true.

OTHER TIPS

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

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]
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top