How to Write C++ Code Without Headers (Repetitive Function Declarations)

C program is running without including Header files?

The compiler is allowed to make things work, but is under no obligation to do so.

You are supposed to declare all variable argument list functions before using them; not declaring printf() properly leads to undefined behaviour (and one valid undefined behaviour is to work as expected).

You should be getting warnings about the undeclared functions if you compile in C99 mode (but Turbo C probably doesn't have a C99 mode).


Nit-picking:

[H]ow can a C program could run without using the standard header file?

All programs run without using any headers whatsoever. However, most programs are compiled using the standard headers to declare the standard functions, and the better programs ensure that all functions are declared before they are used (or are defined as static functions before they are used).

C99 requires this, though many compilers will allow errant programs to compile. However, the compilation should produce a diagnostic; the diagnostic may or may not lead to the compilation failing. In practice, it usually doesn't cause the compilation to fail, but it could and with some compilers (GCC, for example) you can force the compiler's hand (e.g. with GCC's -Werror=missing-prototypes -Werror=old-style-definition options).

Do including header files make the program heavier in c

Including header files inserts all the content from them into the translation unit on pre-processing.

If the include has only declarations(which is usually the case) and the functions are implemented in library files, the code doesn't get heavier. If the header files include implementation, it will be compiled on compilation, thus making the file heavier.

You can read more about compilation steps here:
http://www.tenouk.com/ModuleW.html

How do I write a C header file that can be used in C++ programs?

It is normal to bracket C header files as follows so they can be used in C++ programs. Check your system header files such as stdio.h and you will probably see this:

#ifdef __cplusplus
extern "C" {
#endif

...

#ifdef __cplusplus
}
#endif

Should I #include a library header?

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.)

Code Ordering in Source Files - Forward Declarations vs Don't Repeat Yourself ?

In C code I use a simple rule:

  • Every C file with non-static members will have a corresponding header file defining those members.

This has worked really well for me in the past - makes it easy enough to find the definition of a function because it's in the same-named .h file if I need to look it up. It also works well with doxygen (my preferred tool) because all the cruft is kept in the header where I don't spend most of my time - the C file is full of code.

For static members in a file I insist in ordering the declarations in such a way that they are defined by instantiation before use anyway. And, I avoid circular dependency in function calls almost all of the time.

For C++ code I tried the following:

  • All code defined in the header file. Use #pragma interface/#pragma implementation to inform the compiler of that; kind of the same way templates put all the code in the header.

That's worked really well for me in C++. It means you end up with HUGE header files which can increase compile time in some cases. You also end up with a C++ body file where you simply include the header and compile. You can instantiate your static member variables here. It also became a nightmare because it was far too easy to change your method params and break your code.

I moved to

  • Header file with doxygen comments (except for templates, where code must be included in the header) and full body file, except for short methods which I know I'd prefer be inlined when used.

Separating out implementation from definition has the distinct plus that it's harder to change your method/function signatures so you're less likely to do it and break things. It also means that I can have huge doxygen blocks in the header file documenting how things work and work in the code relatively interruption free except for useful comments like "declare a variable called i" (tongue in cheek).

Ada forces the convention and the file naming scheme on you. Most dynamic languages like Ruby, Python, etc don't generally care where/if you declare things.



Related Topics



Leave a reply



Submit