I know that some functions like sin
cos
min
max
memcpy
may be treated not as normal functions but may be replaced by built-in functions (which may be more optimal than merely inline function calls, when the replacement is (an) actual processor instruction(s), such as directly calling the FSIN
instruction for standard sin
function when compiled for an x86 with a floating point unit).
The question I would like to use power of built-in functions (in C/C++ mostly in mingw/gcc maybe other compiler) but I do not want to link to libc, the Standard C Library).
Is it possible to use builtins with not linking to libc?
Are they any command line flags needed to optimize those symbols as a built-ins?
(Related to previous, but rephrased)
Will they be automatically recognized by name, or are compiler flag(s) necessary to enable usage of built-ins?
Lets say you wanted to replace the function cos
, all you have to do is replace every occurance of cos
in your code with __builtin_cos
. The same goes for any other function that you can replace with the compiler's version. Just prepend __builtin_
to the name.
For more information consult the gcc manual.
@randomusername has already explained the usage of the __builtin_
prefix for many common Standard C Library functions. I recommend using #define
to make the change, while keeping your code clean.
#include <math.h>
#define cos __builtin_cos
#define sin __builtin_sin
#define printf __builtin_printf
...
printf("Distance is %f\n", cos(M_PI/4.0) * 7);
...
No Standard C Library
Now to not use the Standard C Library, which means not linking to it, or including the typical startup and exit code stubs, well, with GCC that is possible with the -nostdlib
which is equivalent to -nostartfiles
and -nodefaultlibs
.
The issue is that you then have to replace all the library functions you would normally use, including system calls (or their wrappers / macros from glibc) for any kernel based functions.
I don't know of a portable or robust method that works across processors or even necessarily different families (sysenter vs. syscall (instruction) vs. int 0x80
for various 32 and 64-bit x86 processors). There is issues with ELF Auxiliary Vectors (Elf32_auxv_t
) and vDSO (virtual ELF dynamic shared object) that may be possible to address and create a portable solution, I don't know.
Entry Point
I believe all GCC environments use the same default entry point, which is the label/function _start
. This is normally included in the "Startup files" and then calls the traditional C/C++ entry point of main
. So you would need to replace it with a minimal stub of your own (which can be in C).
Program termination
I don't know how to replace _exit(rc)
or similar function required to correct terminate the program, in a portable fashion. For example in a Linux environment it needs to make a system call to the kernel function SYS_exit
(aka __NR_exit
or sys_exit
)
void _start(void) {
int rc;
/* Get command line arguments if necessary */
rc = main(0, NULL);
your_exit_replacement(rc);
}
Alternatives
Normally user processes i.e. application programs, as opposed to Operating System kernels or drivers, accept the overhead of linking the Startup Files and the necessary overhead to enable dynamic linking to the Startard C Library, as memory is considered cheap and readily available that for any real (actually does something) application the memory saving is not worthwhile. In embedded domain, where it is not as acceptable to just assume plenty of memory is available, the alternative is the use a minimal libc replacement. For Linux there are several available (e.g. musl, uClibc, dietlibc), I don't know if there is one available for mingw or Windows-compatible open source replacements (ReactOS, and Wine).
Further
For further information, from a Linux platform point of view, there is a nice introduction "Hello from a libc-free world!" Part 1 and Part 2 by Jessica McKellar blogging at Oracle. There are also a number of related questions, and some (partial in some cases) answers here at stackoverflow about using -nostdlib in various circumstances.
Where to go from here depends on your goals: education, embedded, tiny program (Linux ELF executable) or Windows PE executable competitions.
Microsoft Windows
There are various articles for a Microsoft Windows environment dealing with .COM and .EXE executables, and Windows PE but using Microsoft's Visual Studio environment or assembly typically. The "classics" are Matt Pietrek's Under the Hood column "Reduce EXE and DLL Size with LIBCTINY.LIB" (January 2001 issue of MSDN Magazine) and "Remove Fatty Deposits from Your Applications Using Our 32-Bit Liposuction Tools" from October 1996 Microsoft Systems Journal. Another article, but I haven't read myself, that appears to have include explanations is "Reducing Executable Size".