c++c++builderc++builder-xe

C++Builder call to undefined functions hypot/ceil/floor/fabs


Recently, after adding one header file to my project, I stopped being able to compile my application - I added blank header file, and then weird errors appeared:

[bcc32 Error] SystemTypes.h(79): E2268 Call to undefined function 'hypot'
[bcc32 Error] SystemTypes.h(511): E2268 Call to undefined function 'ceil'
[bcc32 Error] SystemTypes.h(525): E2268 Call to undefined function 'fabs'

Those errors came "from nowhere" - I also played with another empty project, and they appeared after changing debug mode to release. How can I fix them? I have no clue why they appeared. Below you can see full parser context of one error:

  Full parser context
    Project3.cpp(3): #include c:\program files (x86)\embarcadero\studio\16.0\include\windows\vcl\vcl.h
    vcl.h(10): #include c:\program files (x86)\embarcadero\studio\16.0\include\windows\vcl\basepch0.h
    basepch0.h(63): #include c:\program files (x86)\embarcadero\studio\16.0\include\windows\rtl\System.Types.hpp
    System.Types.hpp(19): #include c:\program files (x86)\embarcadero\studio\16.0\include\windows\rtl\SystemTypes.h
    SystemTypes.h(32): namespace System
    SystemTypes.h(32): namespace Types
    SystemTypes.h(33): class TSmallPoint
    SystemTypes.h(87): decision to instantiate: double TSmallPoint::Distance(const TSmallPoint &) const
    --- Resetting parser context for instantiation...
    SystemTypes.h(84): parsing: double TSmallPoint::Distance(const TSmallPoint &) const

Solution

  • Short answer: As @Flame spotter said, #include <math.h>.

    Long answer: These messages are telling you what's wrong:

    SystemTypes.h(87): decision to instantiate: double TSmallPoint::Distance(const TSmallPoint &) const
    --- Resetting parser context for instantiation...
    SystemTypes.h(84): parsing: double TSmallPoint::Distance(const TSmallPoint &) const
    

    So the compiler is trying to instantiate TSmallPoint::Distance and ran into a problem. If you look at the implementation for TSmallPoint::Distance, you'll see something like this:

    double Distance(const TSmallPoint& p2) const _ALWAYS_INLINE {
      return hypot(p2.x - this->x, p2.y - this->y);
    } 
    

    And there's the mystery reference to hypot that was giving you trouble. The fact that SystemTypes.h refers to hypot without including <math.h> itself is a bug. It's fixed in my copy of XE2 (I don't have XE around any more to check myself), but you should be able to work around it by including <math.h>. (You could even edit SystemTypes.h and add the include there if you want.)

    As to why it's showing up in release builds not but debug builds - I'm not sure. It's an inline function, and inline functions are typically handled differently in release builds versus debug builds, and the reference to "instantiate" sounds like there may be some template instantiation going on too, which can further complicate things. C++Builder's compiler isn't very standards-compliant, and I don't always understand how and when it decides to complain about something.