How does g++ not report error with the given code?

余生颓废 提交于 2019-12-31 03:04:41

问题


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




回答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

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!