How does g ++ not report an error with this code?

This is a continuation of my answer to why the past tense gives me the result 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 goal of the last line in main :

  cout << "Your elapsed time is " << elapsedtime(time1, time2) <<endl; 

How can g ++ compile the first version without errors?

+2
source share
3 answers

std::ostream has operator << (bool) , and function names are implicitly converted to bool by standard (by converting the function to a pointer, followed by a logical conversion). The corresponding language (§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, pointers to member conversions, and logical conversions.
  • Zero or one qualification conversion.

A value of a function of type T can be converted to a prvalue of type "pointer to T." The result is a pointer to a function.

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 . Zero value, null pointer value or null element pointer value is converted to false ; any other value is converted to true .

+2
source

Given the appropriate warning levels, GCC will alert:

test.cpp|14 col 39| warning: the address of 'int elapsedtime(int, int)' will always evaluate as 'true' [-Waddress]

See GCC 4.7 in Coliru and clang too

+4
source

Because it is fully valid C ++.

The function name is implicitly converted to a pointer to this function.

For MSVC, the standard library provides an output operator for arbitrary pointers, which prints the numeric value of that pointer.

For GCC / Clang, the result is a bit complicated: they (correctly) do not implement an insert 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 so.

 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 the function name to true to true with a warning similar to:

 warning: address of function 'elapsedtime' will always evaluate to 'true' [-Wbool-conversion] 
+3
source

Source: https://habr.com/ru/post/1213934/


All Articles