c++visual-studioc-libraries

Removing math.h from a project VS 2015 / 2017


So, I'm working on a project where I'm intended to implement my own versions of the trigonometric functions, square root, rounding & exponents without assistance from the math.h or cmath libraries that must be done using Visual Studio 2015 or 2017. I'm accustomed to working with GCC, where when not explicitly including math.h or cmath their respective functions are not linked. In my empty, freshly installed Visual Studio projects upon including only iostream, I seem to acquire the ability to use the sin, cos and tangent functions, as well as an error for repeat declarations of functions. I have since created a dummy project freshly on both computers (One is a work computer running a fresh installation of VS2017, the other is a personal computer running VS2015) and stripped out all linked libraries, and am still unable to find a way to remove the mathematics libraries from being included when I only have

#include <iostream>

int main()
{
    float n = sin(3.1415f);
    return 0;
};

in my entire project. I'm unsure how, without being linked to external files, with rebuilding the project, and without any other includes, I'm able to access the sin() function. Further if I change my file to

#include <iostream>

float sin(float n)
{
    return 1.0f;
};

int main()
{
    float n = sin(3.1415f);
    return 0;
};

It presents me with C2382. This occurs whether or not my external dependencies has other files in it or not. How would I go about removing the inclusion to math.h while maintaining access to basic functionality such as printf(), std::cout, and system("PAUSE"); for the purpose of this project like I would in a GCC environment?


Solution

  • Any standard library header may include any other; in VC++ the include path ending at <cmath> is iostream->istream->ostream->ios->xlocnum.

    However in general including math.h/cmath should not in itself be a problem so long as the replacements you define have identical signatures and that you do not indirectly or otherwise use any interfaces that you have not defined. That is to say, it is not math.h that you need to remove - that is useful in ensuring comparability between the standard and your implementation. Rather what you need to do is prevent the linker from linking the math library (while still presumably linking other parts of the C library.

    Unfortunately, this is not possible in VC++ because unlike GCC where mlib and cstdlib are separate libraries, in VC++ the entire standard library is a single entity. Moreover the C++ standard library has dependencies on that library, so you would have to replace more than just the math functions in order to avoid linking the standard library at all.

    It is possible to instruct VC++ to ignore default libraries as follows:

    enter image description here

    but the monolithic nature of the standard library means that it will not help you much, since there are numerous other dependencies on even the simplest empty main() code because all the C run-time environment (the kind of stuff that is in crt0.o in GCC) is included in the same library.

    Your best approach is to continue with your functions in their own namespace - that is after al what namespaces are for. In you library header file you could include macro definitions to avoid linking standard math functions:

    #define sin mymath::sin
    

    But that is not entirely satisfactory - if your header is included before any standard header that includes math.h (directly to indirectly), it may fail to link or even compile in ways that may be hard to fathom.