Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is <cmath> or <math.h> really needed? Compiles without it

So, I have the following code, and it builds and runs perfectly, tried various values and all is well. You'll notice I use log10 function and I do not include cmath or math.h. Why does it still build and run fine? Are those libraries really needed? Why/Why not? Does it have anything to do with me using visual studio? Like, would it not compile if say I was using a different IDE or command prompt to compile it?

#include <iostream>
#include <iomanip>
using namespace std;

int main()  {

    cout << "Classify solutions as acidic or nonacidic" << endl<< endl;

    //declaring double molar concentration
    double mc = 1;

    //using while and if statements to calculate pH in fixed notaion and acidic  or nonacidic
    while (mc != 0)
    {
        cout << "Please enter a molar concentration (or enter 0 to exit): ";
        cin >> mc;

        if (mc != 0)
        {
            cout << "Molar Conentration = " << scientific << mc << endl; //scientific notation

            double pH = -log10(mc);
            cout << "pH = " << fixed << setprecision(6) << pH << endl;  //6 deciumals

            if (pH > 7)
            {
                cout << "Nonacidic" << endl << endl;
            }
            else if (pH < 7)
            {
                cout << "Acidic" << endl << endl;
            }
            else
                cout << "Neutral" << endl << endl;
        }
    }

    //end program when inputing 0
    cout << "End of Program" << endl;

    return 0;
}
like image 293
cb1295 Avatar asked Mar 30 '15 03:03

cb1295


People also ask

Do you need to include cmath in C++?

Cmath library is an essential part of the C++ programming language as it provides many operations and functions of mathematics when we use the programs to execute source codes.

Is there a difference between math H and cmath?

The math module supplies mathematical functions on floating-point numbers, while the cmath module supplies equivalent functions on complex numbers.

What is cmath used for?

The cmath header file contains definitions for C++ for computing common mathematical functions. Include the standard header into a C++ program to effectively include the standard header < math. h > within the std namespace.

Why do we use cmath in C++?

The C++ <cmath> header file declares a set of functions to perform mathematical operations such as: sqrt() to calculate the square root, log() to find natural logarithm of a number etc.


2 Answers

The code:

i = i++ + ++i;

may also compile okay, but that doesn't make it a good idea :-)

It would be wise to include headers for library functions that you use. You don't lose any functionality by doing so but you do guarantee the functionality will work (misuse notwithstanding).


Detailed analysis follows.

Even if an implementation is relaxed about this, the standard mandates it. C++11 17.6.2.2 Headers /3 states:

A translation unit shall include a header only outside of any external declaration or definition, and shall include the header lexically before the first reference in that translation unit to any of the entities declared in that header.

The gcc compiler, for example, will grumble bitterly about your code:

xyzzy.cpp: In function 'int main()':
xyzzy.cpp:22:34: error: 'log10' was not declared in this scope
             double pH = -log10(mc);
                                  ^

As to why VC++ seemingly violates this rule, it has to do with the fact that header files are allowed to include other header files.

If you compile your code to produce pre-processor output (with /P), you'll find a line buried deep within it thus (at least in VS2013):

#line 1 "c:\\blah\\blah\\vc\\include\\cmath"

And a bit of analysis turns up the following hierarchy of includes:

iostream
    istream
        ostream
            ios
                xlocnum
                    cmath

(<xlocnum>, one of the internal headers used by <locale>, appears to need ldexp() from the <cmath> library, though there may be others as well).

That's further evidenced by the fact that VC++ does complain about the following code:

//#include <iostream>
using namespace std;

int main()  {
    double oneHundred = 100;
    int two = log10 (oneHundred);
    return two;
}

with:

error C3861: 'log10': identifier not found

but that error disappears the instant you uncomment the iostream inclusion line.


However, as previously stated, that is not behaviour you should rely on. If you are going to use a library function (or macro/template/whatever), it's up to you to include the correct header.

Otherwise your program compiling correctly is simply an accident.

like image 164
paxdiablo Avatar answered Oct 09 '22 08:10

paxdiablo


As you've noticed, the code snippet you provided works in Visual Studio but not with other compilers. This is because of how the standard library is implemented for each compiler.

It turns out that when you include Visual Studio's implementation of <iostream>, you end up including a bunch of other headers indirectly, and one of these headers is <cmath>.

To see the exact chain, navigate to the standard library include directory. For me (I use Visual Studio 2013 Community Edition) this is located at

C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\include

  1. Open iostream. Note the line #include <istream>
  2. Open istream. Note the line #include <ostream>
  3. Open ostream. Note the line #include <ios>
  4. Open ios. Note the line #include <xlocnum>
  5. Open xlocnum. Note the line #include <cmath>

Guess what? You included cmath when you included iostream... so your code is good to go, on Visual Studio at least. But, don't rely on implementation details or your code will break if you try to migrate it to another platform/toolchain.

For example, trying to compile the provided snippet using g++ on Cygwin results in the following error:

temp.cpp: In function ‘int main()’:
temp.cpp:22:34: error: ‘log10’ was not declared in this scope
             double pH = -log10(mc);

This must mean g++'s implementation of <iostream> doesn't depend on <cmath>

like image 22
Will Resond Avatar answered Oct 09 '22 07:10

Will Resond