Transferring an edited version of selected comments (mostly mine) into an answer.
Include the header - the header author may change something in the header file that might cause all sorts of isssues for your code. pm100
Note the C standard explicitly says (§7.1.4 Use of library functions ¶2):
Provided that a library function can be declared without reference to any type defined in a header, it is also permissible to declare the function and use it without including its associated header.
What you're thinking of doing is allowed (with caveats), but doing so is ill-advised. Use the header.
You're worrying about micro-optimizations. Don't! Unless the chip speed on the computer where you do the compiling is measured in double-digits of megahertz or less, you are wasting your time in order to save minuscule amounts of computer time.
- Include the headers. Include the standard headers.
If you get to 50 headers in a module, then perhaps you might start worrying. You're not there yet. And if the headers are written correctly, you still won't beat including them. Using the header protects you against changes in the declarations in the header. There's little more frustrating than finding that a header was not included but some declarations were written out longhand, and then the function was changed in the header, but you didn't know because you didn't use the header. This is a double-maintenance nightmare — or worse than a double-maintenance nightmare if you have the old version of the function declarations in more than one file.
Generally speaking, the header only declares the function and supporting information needed to call the function (types, macros). The implementation of the function is in a library that is linked separately. You use the header for the declarations so you can call the functions — their implementation is in the library that is loaded while linking and executing your program. You don't get a copy of the functions in your code — there's a library that supplies the function when you link the program. So, including <stdlib.h>
makes a wide variety of functions available for calling, but doesn't add any of them to your object file.
You don't reimplement what's in the library unless it is defective. You use the library, and to use the library, you use the header. The header contains the declarations of the functions; the library contains the implementations of the functions. If it is the standard C library code, or the POSIX library code, or the O/S extra functions, you're going to get a shared library loaded at runtime. If you use static linking, the functions are linked into your executable. Either way, you don't worry about it — not while you're learning, nor later usually.
You are worrying about micro-optimizations. You should not worry about micro-optimizations yet. Not for a long time.
You seem to want an answer to the effect that "Don't include the header because of all the junk in it that will make your program bigger than necessary". That's not a correct answer because including a header does not make your program bigger than necessary.
- A header only includes declarations — not definitions.
- Declarations don't take up space in your executable (though they take up some space in the compiler).
- Definitions do take space in your executable.
If your system uses shared libraries at runtime, the whole shared library will be in memory. However, all the processes that use the same shared library will be using the same memory for the code (but each will have its own copy of any modifiable data), so there's a net win on memory space.
Static linking alters the space equation. A statically-linked program will contain the functions it uses, and the functions those functions use, but won't contain anything that it doesn't need. That will all be separate from the code used by any other program, so if you have multiple statically-linked programs running, each program will have its own image in memory, including its own copy of any library functions. If you have your own implementations of any functions linked into your program, those will occupy separate memory per program because they are statically linked.
And, if your program uses any shared libraries, those will still be loaded on the system, so there'll be overhead for the functions in the shared libraries that you're not using.
It's not a question of portability; it's not a question of the runtime efficiency of your replacement functions. It's a question of sanity and basic good software engineering. You don't re-create code with a very good reason.
And (the key point), including a header doesn't make your program grow.
(NB: C++ does have 'header-only' libraries with templates — the Boost libraries are a primary example. Including such headers means that the functions called by your code may be instantiated using the information from the header. The linker normally manages to avoid too much overhead by eliminating duplicate copies of instantiated functions. So, you still don't have to worry much about program growth because of including headers. Header-only libraries are rare in C.)