The standard library function abs() is declared in stdlib.h, while fabs() is in math.h.
Why are they reside in different headers?
math.h first appears in 7th Research Unix. It is hard to tell how it got there. For example, [1] claims that bits of C library were merged from "PWB/Unix" which included troff and C compiler pcc, but I cannot prove it.
Another interesting piece of information is library manual from V7 Unix:
intro.3:
(3) These functions, together with those of section 2 and those marked (3S),
constitute library libc, which is automatically loaded by the C compiler
cc(1) and the Fortran compiler f77(1). The link editor ld(1) searches
this library under the `-lc' option. Declarations for some of these
functions may be obtained from include files indicated on the appropri-
ate pages.
<...>
(3M) These functions constitute the math library, libm. They are automati-
cally loaded as needed by the Fortran compiler f77(1). The link editor
searches this library under the `-lm' option. Declarations for these
functions may be obtained from the include file <math.h>.
If you look into V7 commands makefiles, only few C programs are linked with -lm flag. So my conclusion is speculative:
libm.a (and math.h) was primarily needed for FORTRAN programs mostly, so it was separated into library to reduce binary footprint (note that it was linked statically).
Not many machines had floating point support. For example, you would need to buy an optional FPP for PDP-11 [2], there is also libfpsim simulation library in Unix to mitigate that, so floating point can be hardly used in early C programs.
1. A History of UNIX before Berkeley: UNIX Evolution: 1975-1984
2. PDP-11 architecture
Most operators like + - / * are also math operators yet these are also readily available. When programming you use so much math, that developers have started to differentiate between math that is needed for everyday stuff and math that is more specialized that you only use some of the time. Abs is one of those functions that are just used to often. Like with pointer arithmetic when you just want to know the difference to calculate the size of a memory block. But you are not interested in knowing which is higher in memory and which is lower.
So to sum up: abs is used often because it calculates the difference of two integers. The difference between two pointers for instance is also an integer. And so it is in stdlib.h. fabs how ever is not something you will need much unless you are doing math specific stuff. Thus it is in math.h.
Related
I got a question from my fellow student friend about why +-/* don't need math.h library to work in C language.
<math.h> contains macro and function definitions for mathematical operations. Some of the functionality in <math.h> is required to be present according to the C Standard, but they still aren't intrinsically part of the grammar of the language, unlike the operators +, -, *, / and %.
Because they are in the standard of C and they are only one instruction in Assembly language. math.h is only the name of the library. That doesn't mean there are no math if you don't include it.
If you look at C Operators, notice they are all fairly simple operations that can be done on numbers and values without the need of a function call (sqrt()). These are part of the C standard and are a basic part of the language, present by default in every program.
The math.h Library contains far more complex mathematical operations, mostly in functions, not small assembly instructions. These do not need to be included in the language because not every program is going to need a square root or a cosine.
Basic operators are part of the grammar of the language. In a lib there are "higher functions" that are composed out of basic operators or other libs. So you can reduce everythink back to the basic constructs of a language ... certainly.
Arithmetic operators are built into the language grammar - they're not separate library calls like sqrt() or abs() or whatever. So, they don't need to have any sort of declaration in scope in order to function.
Primarily, the reason math.h is needed for some operations and not others is that the people who designed C decided to build some things into the core language and to keep some things in separate sets, including a set of things for math, a set of things for strings, a set of things for time, a set of things for input and output, and so on.
It would be possible to build the things in math.h into the core language. For example, sizeof is built into the language, so building sqrt into the language too would not require any change of grammar. Also, it would be theoretically possible to exclude some operations like * from the core language and require you to include math.h before using them. However, the language provides ways for declaring functions like sqrt but does not provide ways for declaring operators like *, so some changes to the grammar would have to be made to support this.
So, since it is possible the core language could include or exclude various things, then the reasons for various things being included or excluded are somewhat a matter of choice. Essentially, the basic arithmetic operations were considered fundamental and very useful, so they were made part of the core language, while other functions were not. There are various factors contributing to this.
One is a desire to avoid cluttering the language. If all of the functions declared in headers were part of the core language, then sqrt could be used only for the sqrt in math.h. A programmer could not use sqrt for their own variable name. This is fine for a few names, but, as the library grows, the chance there will be collisions between a name in a library and a name in regular source code grows.
Additionally, if there is existing source code and somebody has a bright idea for a new routine, adding the new routine name to the language might break existing code that is already using that name for a different purpose.
So, generally, we prefer to implement non-essential routines in separate sets, and then authors can choose to include the ones they want to use and learn, and they can leave out the ones they do not need and avoid problems.
Partitioning the libraries into sets like this also means that library routines not used by a program do not have to be linked into the final program executable, so the executable file can be smaller.
Additionally, it means C can be used in a variety of environments, such as a small machine that is not able to support the full math library. Somebody might want to run simple programs that just work with basic arithmetic on a small processor. If the core language of C is small, they can write such programs. If every C program had to include all of the routines on the libraries, it might not be possible to get C working on very small computers.
I'd like to know how C Header Files and ABIs relate. The sizes of various types are architecture and even compiler-dependent. Then how can one reliably link to a C library?
For a more specific problem: When using Haskell's FFI, one even only uses Haskell types like CDouble to define (duplicate the definition of) the C library interface. I don't know where the binary type size information is coming from. What is the trick for making the linking work?
Please see this link https://code.google.com/p/tabi
It may help you to avoid difficulties with possible ABI differences between Haskell and C.
The library type information comes from magic macros that are run to insert information grabbed from the C compiler by autoconf.
For example, see the definition of CDoublehere: https://hackage.haskell.org/package/base-4.8.2.0/docs/src/Foreign.C.Types.html#CDouble
and then see where the HTYPE_DOUBLE size comes from in this autoconf input here: https://hackage.haskell.org/package/base-4.8.2.0/src/include/HsBaseConfig.h.in
Since GHH compiles against the compiler/arch it is compiled with (except in the special cross-compiler modes, which are new and different in ways I'm not fully cognizant of) this makes everything tie out with the ABI properly.
I need to track down how exactly is double sin(double x) implemented in eglibc-2.13. I downloaded the source code and the only part that made sense was __sin function, that was platform-specific. Is it the heart of what I have in /usr/lib/i386-linux-gnu/libm.a?
How to track down the macrodefinitions that lead from sin() to __sin()? What I really need is the exact code (filename and the line is enough) and a way in which the build process deduces which implementation to use. The architecture's i386.
The (e)glibc build process is black, black magic. You do not want to try to comprehend it. However, glibc adheres to a one-file-per-public-function coding style, so in general, if you have the source tree and you want to find the implementation(s) of some function, the easiest thing to do is
$ find * -name '*function*' -print
from the top level, replacing function with the name of the function, of course.
Talking specifically about sin: the generic implementations of the math functions are in the math directory: however, it appears that there is no generic definition of sin. So the next place to look is sysdeps. Everything that isn't generic is in sysdeps, and in particular, sysdeps/ieee754 is where all the math functions that have some dependence on the IEEE 754 floating point specification, but no other system dependencies, live. This directory is organized by type: sysdeps/ieee754/dbl-64 contains all the math functions for IEEE double. And here you will find sysdeps/ieee754/dbl-64/s_sin.c, which is the code you are looking for. (The e_, s_, k_, etc prefixes on all these files used to mean something but AFAIK no longer do.)
If there were an implementation of sin in assembly language for a particular processor, it would be in a file named sin.S (or possibly s_sin.S) somewhere else in sysdeps. It does not appear that there is one, though.
Not an answer, but just a bit of a background:
When you use sin() or cos() in your C code, it is almost certainly the compiler that provides the implementation, rather than your C library. As an example, look at the list of builtins GCC provides. The linked page also describes the cases where the built-ins are used rather than the versions the C library provides.
This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Why do you have to link the math library in C?
When I write a program that uses functions from the math.h library, why is it that I have to explicitly link to libm even though they are part of the C standard library?
For instance, when I want to use the sin() function I need to #include <math.h> but I also need to pass -lm to GCC. But for any other library from the standard library, I don't have to do that. Why the difference?
In the old days, linkers were slow and separating the mostly unused math code from the rest made the compilation process go faster. The difference is not so great today, so you can add the -lm option to your default compiler configuration.
Note that the header <math.h> (or any other header) does not contain code. It contains information about the code, specifically how to call functions. The code itself is in a library. I mean, your program does not use the "<math.h> library", it uses the math library and uses the prototypes declared in the <math.h> header.
It's the same reason you have to explicitly link to libpthread on most implementations. When something new and scary is added to the standard library, it usually first gets implemented as a separate add-on library that overrides some of the symbols in the old standard library implementation with versions that conform to the new requirements, while also adding lots of new interfaces. I wouldn't be surprised if some historical implementations had separate versions of printf in libm for floating point printing, with a "light" version in the main libc lacking floating point. This kind of implementation is actually mentioned and encouraged for tiny systems in the ISO C rationale document, if I remember correctly.
Of course in the long-term, separating the standard library out like this leads to a lot more problems than benefits. The worst part is probably the increased load time and memory usage for dynamic-linked programs.
Actually, the reason you normally don't need to link against libm for most math functions is that these are inlined by your compiler. Your program would fail to link on a platform where this is not the case.
I read that the pow(double, double) function is defined in "math.h" but I can't find its declaration.
Does anybody know where this function declared? And where is it implemented in C?
Reference:
http://publications.gbdirect.co.uk/c_book/chapter9/maths_functions.html
Quite often, an include file such as <math.h> will include other header files that actually declare the functions you would expect to see in <math.h>. The idea is that the program gets what it expects when it includes <math.h>, even if the actual function definitions are in some other header file.
Finding the implementation of a standard library function such as pow() is quite another matter. You will have to dig up the source code to your C standard runtime library and find the implementation in there.
Where it's defined depends on your environment. The code is inside a compiled C standard library somewhere.
Its "definition" is in the source code for your c standard library distribution. One such distribution is eglibc. This is browsable online, or in a source distribution:
w_pow.c
math_private.h
Short answer: In the C standard library source code.
The actual implementation of pow may vary from compiler to compiler. Generally, math.h (or a vendor-specific file included by math.h) provides the prototype for pow (i.e., its declaration), but the implementation is buried in some library file such as libm.a. Depending on your compiler, the actual source code for pow or any other library function may not be available.
declared: in the include directory of your system/SDK (e.g.: /usr/include;/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS3.2.sdk/usr/include/architecture/arm/math.h)
defined (implemented):
as library (compiled, binary code): in the library directory of your system/SDK (e.g.: /usr/lib (in case of the math library it's libm.dylib)
as source (program code): this is the interesting part. I work on a Mac OS X 10.6.x right now. The sources for the functions declared in math.h (e.g.: extern double pow ( double, double ); ) are not shipped with the installation (at least I couldn't find it). You are likely to find those sources in your system/SDK's C library. In my case the math library (libm) is a separate project, some of its sources are provided by Apple: http://www.opensource.apple.com/tarballs/Libm/Libm-315.tar.gz
The extern keyword in the function declaration of pow means, that it's defined somewhere else. Math functions are low-level high-performance implementations mostly done in assembly code (*.s). The assembly routines (taking the arguments/giving the parameters via registers/stack) are linked with the rest of the C library. The linking/exporting of the function/routine names is platform specific and doesn't really matter if ones goal is not dive into assembly coding.
I hope this helped,
Raphael
If you are seeking how the calculation is implemented, you can find it here:
http://fossies.org/dox/gcc-4.5.3/e__pow_8c_source.html
The name of the function is __ieee754_pow
which is called by pow function.
I’s really defined in math.h. Have you tried including math.h and simply using pow? What do you mean by “can't find it”?
Here's a C implementation for fdlibm: http://www.netlib.org/fdlibm/e_pow.c
For what it's worth, when v8 dropped its cos/sine tables, it pulled from fdlibm's implementation to do so: https://code.google.com/p/v8/source/detail?r=22918
From the change commit comments: "Implement trigonometric functions using a fdlibm port."
Mozilla on the other hand calls the cstdlib math functions, which will have variable performance by build and system (ex: may or may not invoke the chip-level implementations of transcendental functions). While C# bytecode seems to make explicit references to chip-level functions when it can. However, "pow" is not one of those, iirc (doesn't seem to have an chip-level function) and is implemented elsewhere.
See also: https://bugzilla.mozilla.org/show_bug.cgi?id=967709
For a cos/sine discussion in the Mozilla community, comparison of Mozilla's implementation vs old v8 implementation.
See also: How is Math.Pow() implemented in .NET Framework?
Intrinsic functions are chip-level, actually implemented on the processor. (We don't necessarily need lookup tables any more.)
Its here and also here.
Also go on wikipedia
You will find pow there.