I'm new to C. I was traveling through math.h, looking for its mathematical algorithms, but encountered only this kind of lines:
_CRTIMP double __cdecl sin (double);
_CRTIMP double __cdecl cos (double);
...
Now, I couldn't find the algorithm itself. I know _CRTIMP is a kind of run-time library C uses, but I just can't figure out what the whole line means. Could you, please, explain?
Besides, I would like to know where these functions are defined at.
C headers typically contain only function prototype declarations, not definitions. Function prototypes specify what is called the "function signature": return value, arguments, and sometimes calling convention (when & where compilers support this). The function definitions are in a separate source file, that gets compiled separately from your own (including any headers your source file #include's). Definitions of library functions might be in C, they might also be in assembly, but that shouldn't matter to your code (only to your curiosity). But you probably don't compile those yourself anyway; instead, your development environment / operating system comes with a standard library (a binary object file) that contains many already-compiled functions. Your development environment simply links your code to that library.
C header files will only contain the declaration of functions, not their definitions.
You're looking for the source code of the functions declared in math.h, here's one implementation of sin: http://fxr.watson.org/fxr/source//arch/i386/math-emu/poly_sin.c?v=linux-2.4.22
The C header files that are included with your OS, compiler, or C runtime library are not really intended for human consumption. You can certainly read them, and you can learn quite a bit by trying to understand them, but they're primarily intended for use by the compiler. As you've seen in these examples, they tend to depend on a lot of compiler-specific features (a habit you should try to avoid in your own code).
They also tend to have a lot of #ifdefs, so the same headers can be used with different systems.
If you just want to know how to use the sin function, for example, you're better off reading your system's documentation. On my Ubuntu system, for example, man sin shows this (among other things):
SYNOPSIS
#include <math.h>
double sin(double x);
float sinf(float x);
long double sinl(long double x);
Link with -lm.
The _CRTIMP and __cdecl are probably important to the compiler, but as a programmer you can safely ignore them.
If you're looking for the source code that implements the sin function, that may or may not be available. It might be written in a language other than C; there have even been systems where it's implemented in hardware (though a small wrapper would still be required).
Another answer provides a link to one implementation, but that's probably not the one used on your system.
And you don't need to get too bogged down in how the sin function is implemented. It's certainly a good thing to know, but you don't need that information to write code that uses it. (I absolutely do not want to discourage curiosity.)
Related
The premise: I'm writing a plug-in DLL which conforms to an industry standard interface / function signature. This will be used in at least two different software packages used internally at my company, both of which have some example skeleton code or empty shells of this particular interface. One vendor authors their example in C/C++, the other in Fortran.
Ideally I'd like to just have to write and maintain this library code in one language and not duplicate it (especially as I'm only just now getting some comfort level in various flavors of C, but haven't touched Fortran).
I've emailed off to both our vendors to see if there's anything specific their solvers need when they import this DLL, but this has made me curious at a more fundamental level. If I compile a DLL with an exposed method void foo(int bar) in both C and Fortran... by the time it's down to x86 machine instructions - does it make any difference in how that method is called by program "X"? I've gathered so far that if I were to do C++ I'd need the extern "C" bit to avoid "mangling" - there anything else I should be aware of?
It matters. The exported function must use a specific calling convention, there are several incompatible ones in common use in 32-bit code. The calling convention dictates where the function arguments are stored, in what order they are passed and how they are removed again. As well as how the function return value is passed back.
And the name of the function matters, exported function names are often decorated with extra characters. Which is what extern "C" is all about, it suppresses the name mangling that a C++ compiler uses to prevent overloaded functions from having the same exported name. So the name is one that the linker for a C compiler can recognize.
The way a C compiler makes function calls is pretty much the standard if you interop with code written in other languages. Any modern Fortran compiler will support declarations to make them compatible with a C program. And surely this is something that's already used by whatever software vendor you are working with that provides an add-on that was written in Fortran. And the other way around, as long as you provide functions that can be used by a C compiler then the Fortran programmer has a good chance at being able to call it.
Yes it has been discussed here many many times. Study answers and questions in this tag https://stackoverflow.com/questions/tagged/fortran-iso-c-binding .
The equivalent of extern "C" in fortran is bind(C). The equivalency of the datatypes is done using the intrinsic module iso_c_binding.
Also be sure to use the same calling conventions. If you do not specify anything manually, the default is usually the same for both. On Linux this is non-issue.
extern "C" is used in C++ code. So if you DLL is written in C++, you mustn't pass any C++ objects (classes).
If you stick with C types, you need to make sure the function passes parameters in a single way e.g. use C's default of _cdecl. Not sure what Fortran uses.
I'm learning C for 2 months. I experimented with different IDEs and my experiments resulted in confusion. Because for e.g. in NETBEANS I can use abs function without stdlib.h library, but when I tried to do the same thing in Visual Studio 2012 it gave a an error. Or a very odd thing in NETBEANS I can use functions from math.h library without declaring the library. Why is this happening? Can someone help? NETBEANS USES cygwin compilers.
In C you don't need to include the headers in order to use the functions. Older compilers don't always warn about that though. Also, different compilers might provide those functions in different ways; on some, they're not functions but macros. With macros, you need to include the headers.
It's good practice to always include the headers that provide the functions you need, so that you get the function prototypes. That's the only way the compiler can check for errors (correct types of passed function arguments, for example.) If you call a function for which you have no prototype, you get an implicit declaration of that function. That means the compiler just takes a guess and hopes you're using the function correctly, but has no way to check. That's why this won't work with macros, since a macro can't have a function declaration (implicit or not.)
The reason Visual Studio gives an error is because it's a C++ compiler, not a C compiler. C++ is a bit different from C. One of the differences is that C++ does not allow implicit function declarations. If you don't declare the functions you use (by including their header file in this case), then that's considered an error. C++ is mostly compatible with C, but that happens to be one of the few differences.
Btw, they're not libraries. They're header files. There's a difference. You have several standard headers you can include, but you only have one library; the C library. On most systems, you also have a math library, which only contains math functions. The point though is that several header files can be (and usually are) part of the same library.
my experience with C has been the same. different compilers has different libraries and sometimes they don't stick to the standards.
some compiler vendors try to lock you in (XXXXX$XXX) :)
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.
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.
I'm now really diving into my OS project, called ForestOS, but now I'm needing to dive more into some simple and basic things of C. As now I'm having many problems with the correct variable to use and functions.
I want resources that only talk about variables, functions and how to develop without headers(stdio.h, math.h and all the others).
Best starting place is probably the book The C Programming Language.
The book was central to the development and popularization of the C programming language and is still widely read and used today.
A guide to OS development suggests CProgramming.com as the best place to start. There's tutorials, links to further resources, and everything for free.
Building an OS is non-trivial, I suggest if you are "having many problems with the correct variable to use and functions" then you may be attempting to walk before you can run!
Quote:
how to develop without headers(stdio.h, math.h and all the others).
I assume that you actually mean that you want to code without using the standard library rather than "without headers". Header files are intrinsic to modularisation in C; if you did not use headers, your code would have to be one monolithic module. Don't confuse headers with libraries.
However, even then there is no need not to use the standard library when writing 'bare-metal' code. You simply need a library that does not have OS dependencies, and you write the low level glue code to make things like stdio and memory allocation work on your system. Such a library is Newlib for example. It will make your life a whole lot easier if you have standard library support.
You only need headers to provide declarations of functions and external variables.
It is possible to eliminate the header files and provide your declarations within the translation unit (a.k.a. source file). Although possible, this is not recommended.
Here is an example of a legal C program without header files:
/* Forward declaration of main(). */
int main(void);
/* Definition for main() function. */
int
main(void)
{
return 13; /* 42 is such an overrated number. */
}
Some reasons for using header files are: code / typing reduction and single point of maintenance. If two modules need the same structure declaration, placing it in a header file will reduce typing (you only have to #include it in both files instead of copying it into both files). Also, if you need to change any declaration, if it is copied, you'll have to hunt down all copies and change every instance vs. making one change in a header file.
As far as standard header files, such as math.h and stdio.h, if you don't need them, don't include them. An OS should not require stdio.h, but may use math.h. Most standard header files do not contribute to the code size; only to the compile time.
I highly suggest you focus on the correctness of your OS and don't worry about trivialities such as header files. After your OS is working correctly and robust, go ahead and trim the fat.
Go through Kernighan C or the book named "Let Us C".It would help you learn much better as a beginner