tags:

views:

259

answers:

5

In Python whenever I had a bunch of functions that I wanted to use across multiple programs I'd make another .py file and then just import that wherever I needed it. How would I do that in C/C++? Do I dump both prototype and implementation into an .h file? or do I need to place the function prototypes in the .h file and the implementations in a separate .cpp file with the same name as the .h file and #include the .h wherever I need it?

+3  A: 

In C/C++ we usually put declarations in .h files and implementation in .c/cpp files.

(Note: there're many other ways, for example the include, templates, inline, extern, ... so you may find some code only in header files or only in c/cpp files - for example some of the STL and templates.)

Then you need to "link" the file with your program, which works like the "import" in Python interpreter but actually works in static linking object files together into a single executable file.

However the "link" command and syntax depends on your compiler and OS linker. So you need to check your compiler for more information, for example "ld" on UNIX and "link.exe" on DOS/Windows. Moreover, usually the C compiler will invoke the linker automatically.

For example, say you have 2 files: a.c and b.c (with a.h and b.h), on gcc:

 gcc -o a.out a.c b.c

On MSVC:

 cl a.c b.c
Francis
the STL is mostly header files, so it might be more accurate to say we _used_ put implementation in .c/.cpp files.
John Knoeller
@John: It really depends what you're doing, template code generally belongs in header files because almost all compilers don't support keyword export. It's fair to say we "don't advise" putting all code in headers in general, though - by the time someone can competently create header-only libraries, they can judge when to ignore that advice :-)
Steve Jessop
+4  A: 

You need to do a couple of things:

  1. Add the prototype to a header file.
  2. Write a new source file with the function definitions.
  3. In a source file that just wants to use the shared function, you need to add #include "header.h" (replacing header.h with the name of the file from step 1) someplace before you try to call the shared function (normally you put all includes at the top of the source file).
  4. Make sure your build compiles the new source file and includes that in the link.

A couple of other comments. It's normal to have foo.h as the header for the foo.c but that is only a style guideline.

When using headers, you want to add include guards to protect against the multiple include issue.

R Samuel Klatchko
A: 

See Francis's answer. The sentence that you wrote, "or do I need to place the function prototypes in the .h file and the implementations in a separate .cpp file with the same name as the .h file and #include the .h wherever I need it?", is pretty-much correct. You don't have to do things exactly this way, but it works.

Sam
A: 

It's up to you how you do this, The compiler doesn't care. But if you put your functions in a .h file, you should declare them __inline otherwise if you include the header file in more than one .cpp file, you will have multiply defined symbols.

On the other hand, if you make them __inline, you will tend to get a copy created in each place that you use the function. This will bloat the size of your program. So unless the functions are quite small, it's probably best to put the functions in a .cpp and create a parallel .h with function prototypes and public structures. This is the way most programmers work.

On the other hand, in the STL (Standard Template Library), virtually all of the code is in header files. (without the .h extension)

John Knoeller
The symbols are only defined more than once if the portion of the header file where the symbols are declared is processed more than once. See my answer for the #ifdef preprocessor statements to keep that from happening. **Inline expands functions inline - this can kill your code size if including functions of any length and complexity. Inline is meant to be an optimization, not a way around fixing your code.**
David Lively
@David: That's what I said. _if you include the header file in more than one .cpp file_. I also said _This will bloat the size of your program_.
John Knoeller
"__inline" is not part of C++ - "inline", on the other hand is.
anon
@John even if you're only reference that .h file from a single cpp file, "inline" is **still** the wrong way to tackle this issue. Bloat in this case is determined by the number of calls, not by the number of source files using the header.
David Lively
A: 

There are two ways to approach this that differ only slightly. As others have said, the first steps are:

-Create a header file which contains your function prototypes. You'll want to mark this with

# ifndef myheader_h

# define myheader_h

// prototypes go here...

# endif

to prevent problems with multiple inclusions.

-Create a .c file which contains the actual definitions.

Here's where the solutions branch. If you want to include the source directly in your project, make the .c file part of your compilation stage as well as your link stage.

However, if you really plan on using this across multiple projects, you'll probably want to compile this source file independently, and reference the object file from your other projects. This is loosely what a "library" is, though libraries may consist of multiple object modules - each of which has been compiled but not yet linked.

update Someone pointed out that this really only keeps the header from being included in a single cpp file. News flash: that's all you need to do.

Compilers treat each cpp file individually. The header files included by each cpp source file tell the compiler, "hey! This thing is defined in another source file! Assume references that match this prototype are A-OK and keep moving on."

The LINKER, on other other hand, is responsible for fixing up these references, and IT will throw a fit if the same symbol is defined in multiple object files. For that to happen, a function would have to be defined in two separate source files - a real definition with a body, not just an extern prototype - OR the object file that contains its body/definition would have to be included in the link command more than once.

Re:"inline" Use of "inline" is meant as an optmization feature. Functions declared as inline have their bodies expanded inline at each place where they are called. Using this to get around multiple definition errors is very, very bad. This is similar to macro expansion.

David Lively
BTW, `#define __myheader_h_` intrudes into the compiler's set of reserved names. Don't use leading underscores; it doesn't buy you anything.
jamesdlin
Noted and updated.
David Lively
this doesn't solve anything. If you include this header in 2 .cpp files, they will both see the exact same view of the header. This #ifdef trick is designed to protect the header from being included twice _in the same_ .cpp file.
John Knoeller
@John, compilers don't treat more than one cpp file at a time, so this works just fine. The only way you'll get symbol redefinition errors at the compiler level is if the symbol is defined more than once, which this fixes. The linker emits "symbol already defined" errors if the symbol really **is** defined more than once.
David Lively