Quantcast
Channel: User Peter - Reinstate Monica - Stack Overflow
Viewing all articles
Browse latest Browse all 233

Answer by Peter - Reinstate Monica for static library, but I still need headers?

$
0
0

Even though you can produce an executable from sources and library files with a single command, conceptually the process involves two steps (which you can perform separately if you wish):

  1. For each file separately: Preprocess (expand include files and macros) and compile into an object file
  2. Link the resulting object files and libraries mentioned on the command line into an executable.

If you think of how compiling a single cpp file works it is clear that any name you use must be declared. You can do that "manually" (simply write e.g. extern double sqrt(double); before you call the function for the first time in your program); in that case you don't need to include math.h which will contain basically the same line. The compiler which sees the code after the include files have been inserted does not know or care where the line comes from.

In the following example I use the standard math library without including the header; I simply declare the sqrt function "manually".

echo $? displays the exit value of the last command (here: our program) which should be the square root of 4:1

$ cat main.cppextern "C" double sqrt(double);int main(){        return sqrt(4.0);}$ g++ -c main.cpp$ g++ -o main main.o -lm$ ./main; echo $?2

1 The return value of main (which becomes the exit value of the program) has type int so that the double returned by sqrt undergoes a "narrowing conversion" before it is returned ("narrowing" because information is potentially lost). This can be tricky: Results of computations which are mathematically integers may result in floats that are very close but not quite equal to that integer. If that value is minimally smaller than the expected result, a conversion to int results in a value that's off by 1, surprisingly. The surprise is compounded because the output functions typically round (also up, when necessary), as opposed to the conversion which always cuts off fractions. Example:

$ cat main.cpp#include <iostream>#include <iomanip>#include <limits>using namespace std;int main(){        double not_1 =  0.3 + 0.3 + 0.3 + 0.1;        cout << not_1 << endl;        int max_precision{std::numeric_limits<double>::digits10 + 1};        cout << setprecision(max_precision) << not_1 << endl;        cout << (not_1 == 1 ? "0.3 + 0.3 + 0.3 + 0.1 == 1"                        : " 0.3 + 0.3 + 0.3 + 0.1 != 1 !") << "\n";        return not_1;}$ g++ -o main main.cpp && ./main; echo $?10.9999999999999999 0.3 + 0.3 + 0.3 + 0.1 != 1 !0

But the quality of implementation of sqrt in libm is such that it returns 2.0 for an argument of 4.0, helped by the fact that small-ish integers are lossless representable in floating point formats. Our original program in the answer does not suffer from precision issues.


Viewing all articles
Browse latest Browse all 233

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>