1

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?

  • Sadly, although I've been developing within a namespace to check my implementations against the standard library, I'm not intended to have the standard mathematics functions even linked to the end-result. This is easy to accomplish in GCC, but as I mentioned, this project has to be in VS.
Khaled.K
  • 5,828
  • 1
  • 33
  • 51
Joseph
  • 53
  • 1
  • 9
  • You could play with macros, for instance after all includes add `#define sin mysin`. – Marc Glisse Apr 17 '17 at 08:39
  • what if you declare your functions in a namespace, and use them instead? – CinCout Apr 17 '17 at 08:41
  • Sadly, I'm not allowed to even have the other functions linked, otherwise I had already been developing them in a namespace to check the output of my functions against the standard library for testing purposes. The macro may be a plausible idea, but I would rather remove the inclusion of the math library so that I'm not including extraneous code or using excessive macros for the roughly 12 functions I will need to overload. – Joseph Apr 17 '17 at 08:44
  • I remember reading somewhere that Visual Studio (or its compiler) includes hard-coded logic to inline the basic math functions. That would be why it complains if you redefine `sin()`. The only real way forward would be to put your own math functions into a separate namespace, and call them by full name (e.g. `y = yourmath::sin(x)`). That won't stop programmers calling the standard versions though - the only way out of that is non-technical (e.g policy settings). And require code to ALSO build with any compiler without `#include ` or ``. – Peter Apr 17 '17 at 08:46
  • Don't spam tags! C is not C++ is not C! And the names of the standard library are reserved in a hosted environment. You must not use them. Use your other names instead. – too honest for this site Apr 17 '17 at 09:01
  • Sorry, the tag spam was actually because this was occurring in a language agnostic manner between both C and C++ and the cstdlib was a part of the overall issue. As I said before though, I need to remove the functions as a whole, not just create new aliases for mine. – Joseph Apr 17 '17 at 09:07
  • @JosephJ. does [this](http://stackoverflow.com/questions/3929831/vc-2010-exclude-library/3929854#3929854) solve your problem, if you write `cmath` in that property? generally, I second @Olaf opinion, don't mess with reserved names. – Khaled.K Apr 17 '17 at 09:17
  • No, it seems that if I set "Ignore all Default Libraries" to yes, it does but it also no longer allows me to include or link iostream. When trying to use "Ignore specific default libraries" to target math.h or cmath, it does not seem to stop their functionality. I imagine this implies that visual studios is linking another default library with their mathematics functions that I may be able to add to this list to stop? – Joseph Apr 17 '17 at 09:27
  • I did not say to create aliases, but use other names for your functions. That is the standard way. – too honest for this site Apr 17 '17 at 11:16

2 Answers2

2

If you are going to implement your own versions of math functions then it would be preferred to wrap them into your own namespace to avoid name collisions.

#include <iostream>

namespace n_my_math
{

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

} // namespace n_my_math

int main()
{
    float n = n_my_math::sin(3.1415f);
    return 0;
};
user7860670
  • 35,849
  • 4
  • 58
  • 84
  • Looks like the OP already knows this solution. He is actually looking for a way to exclude `cmath` functions (if that's possible) – CinCout Apr 17 '17 at 08:53
1

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.

Clifford
  • 88,407
  • 13
  • 85
  • 165