1

I have a function that is the same across all my header files and main.cpp if I define it in main.cpp will they all be able to use it once they are included or will they have a compiler issue?

Still new to this whole header file business. Thanks in advance.

ChasingLogic
  • 429
  • 4
  • 7
  • ... Did you try it? Do you get any errors? – user229044 Nov 21 '13 at 17:41
  • 1
    If you have a function that's the same across all header files, just put it in a single header file which is included by the other header files. And yes, you can define it in any source file, although doing so in main.cpp would be unconventional. Generally if you have a "foo.h", the functions contained therein are defined in a "foo.cpp". – Taylor Brandstetter Nov 21 '13 at 17:41

5 Answers5

5

In the header file (myfunction.h), you need to have only declaration of the function:

int foo(int param);

In the main.cpp (or any other cpp file - better choice would be myfunction.cpp - just make sure definition is included in exactly one file!) file, you need to have definition of the function:

int foo(int param)
{
   return 1;
}

In all other source (cpp) files where you're using function foo, just include myfunction.h and use function:

#include "myfunction.h"

void someotherfunction()
{
    std::cout << foo(1) << std::endl;
}

Compiler only needs to see declaration of the function before it is used. Linker will connect definition of the function with the places you've used the function. If you forget to write definition in main.cpp file, you will not get compiler, but a linker error. It may be worth of mentioning that compiler is compiling each cpp file separately, and linker's job is to combine all compiler object files and to produce final output file. On most setups, linker will be called automatically after compiling, so you may not be familiar with it.

If you include entire function definition in the header file, that definition will be compiled in each translation unit where header file is included, and you will get multiple symbol definition linker error, or something similar - that's why you need to include only declaration of the function inside header file. However, there are exceptions for this - for example, you may declare your function inline - other answers explain this approach.

So, now myfunction.h contains the function declaration:

#ifndef MY_FUNCTION_H
#define MY_FUNCITON_H

// declaration
int myfunction();

#end if

myfunction.cpp contains the function definition:

int myfunction()
{
    return 4;
}

Now, in file1.cpp and in file2.cpp you want to use this function, so you're including myfunction.h:

// file1.cpp
#include "myfunction.h"

// somewhere in the file
void foo()
{
    std::cout << myfunction();
}

... and in the second file:

// file2.cpp
#include "myfunction.h"

// somewhere in the file
void bar()
{
 /// ...
 std::cout << myfunction();
}
Nemanja Boric
  • 21,627
  • 6
  • 67
  • 91
  • You make it sound like this is the only solution. It isn't. Proper use of the `inline` keyword should at least be mentioned. – IInspectable Nov 21 '13 at 18:05
  • Let me make sure I got this right. I have file1.h file2.h file3.h and main.cpp I should make a file like thisfunction.h which has the function write an #include in every header file? I though that's exactly what you weren't supposed to do. – ChasingLogic Nov 21 '13 at 18:45
  • @ChasingLogic No. You need to make a file `thisfunction.h` where it will be declaration of the function (`int foo();`). You need to write `#include "thisfuction.h"` (with quotes, as it is your header file in all cpp files which are calling function `foo`. – Nemanja Boric Nov 21 '13 at 19:06
  • @IInspectable can you tell me why did you downvoted my answer again? – Nemanja Boric Nov 21 '13 at 19:07
  • So then after writing the thisfunction.h I include it in main.cpp only and "prototype" it in file1.h and file2.h like so void thisfunction(int x); – ChasingLogic Nov 21 '13 at 19:08
  • @ChasingLogic I will give you an example. – Nemanja Boric Nov 21 '13 at 19:09
  • @Nemanja First, you need to link me to the moderation tool that is unlocked somewhere in between 2673 and 9755 reputation, that lets you see **who** voted on a question/answer. – IInspectable Nov 21 '13 at 19:12
  • @IInspectable well, if your reputation suddenly drops by 1, just as my answer is downvoted... – Nemanja Boric Nov 21 '13 at 19:13
  • So that's not my problem though. I don't have multiple .cpp files that use the function I have multiple .h files that use it. Does that matter? The only reason I ask because I was told not to use #includes in .h files unless there is a very good reason for doing so. – ChasingLogic Nov 21 '13 at 19:20
  • @ChasingLogic, well, as I can see it from here, if you really use that function in your header file (for example, because of the templates), there's nothing wrong about including header file inside other header. However, you should consider if you can move functions in multiple .h files to separate cpp files and leave only function prototypes in header files. – Nemanja Boric Nov 21 '13 at 19:23
  • @Nemanja You should seriously consider, that there are interesting questions and answers outside your little universe. If I find an answer that is misleading and/or wrong, I take the freedom to downvote. This answer is not particularly brillant, but not wrong/poor enough for me to consider a downvote. In the future I would appreciate it if you didn't jump to conclusions all that quickly. – IInspectable Nov 21 '13 at 19:24
  • @ChasingLogic Or go with the solution I proposed. The one that solves **all** scenarios you are having problems with. – IInspectable Nov 21 '13 at 19:26
  • @IInspectable Sorry, I just can't see what exactly is different in your solution when it comes to including header files. – Nemanja Boric Nov 21 '13 at 19:29
  • @Nemanja In short: The `inline` keyword. It solves the issues revolving around multiply defined symbols. Regardless of how often you include a module that **defines** a function declared as `inline`, the linker will clean up the mess, making sure that the single-definition-rule is not violated. Small change - big difference. – IInspectable Nov 21 '13 at 20:22
2

Header files in C and C++ are a language artifact. They are the consequence of the fact, that C and C++ can be implemented as a single-pass compiler. In contrast, Pascal - for example - has a two-pass compiler, that skips over unknown entities during the first pass, and fills in the missing bits in a second pass. Consequently, in C and C++ every type, object, and method must be declared before it can be used. This is the main responsibility of header files.

Header files are expanded into any file that includes them. In other words: The preprocessor replaces the statement #include "foo.h" with the contents of the file "foo.h". With this being the case you need to be careful to not violate the single definition rule: An entity must not be defined more than once.

To meet both requirements you have two options: Declare and define the function in the header, using the inline keyword, or declaring it in the header only, and defining it in another compilation unit.

The following code illustrates both solutions:

// foo.h

inline void foo() {
    // Method is implemented in this header file.
    // It is marked 'inline' to prevent linker errors
    // concerning multiply defined symbols.
    ...
}

Delaration in header only, implementation in another compilation unit:

// foo.h

extern void foo();


// foo.cpp (or another compilation unit)
void foo() {
    ...
}

Regardless of which solution you go with, you can use foo() from any compilation unit. If you want to use it from "main.cpp" the code would look something like this:

// main.cpp
#include "foo.h"

int main() {
    foo();
}
IInspectable
  • 46,945
  • 8
  • 85
  • 181
  • There's no need for `extern` linkage qualifier in the header file before function declaration. – Nemanja Boric Nov 21 '13 at 18:13
  • @Nemanja There is no need for the `extern` storage class specifier in this example, as this function has external linkage by default. I explicitly used it to make it obvious, though. See [Storage class specifiers](http://en.cppreference.com/w/cpp/language/storage_duration): *"Any of the following names declared at namespace scope have external linkage: ... functions [...] not declared static, and not declared const"* – IInspectable Nov 21 '13 at 18:32
0

So you have a function which is used in all your header files, why don't you make a utility.h which keeps track of these types of functions and inline the functions in the .h ?

0

Declare the function prototype in a custom header file:

int add(int a, int b);

let say header file name is myfunction.h and include it wherever you need the function.

now you can define a function on another.cpp or main.cpp

int add(int a, int b){
   return a+b;
}

include your custom header file like this:

#include "myfunction.h"

remember your main.cpp and other cpp files and the new header file should be in the same path.

Guilherme Bernal
  • 8,183
  • 25
  • 43
Md. Al-Amin
  • 1,423
  • 1
  • 13
  • 26
  • **Define** functions on header files? This is exactly what one should not do. – Guilherme Bernal Nov 21 '13 at 17:50
  • @Guilherme Defining functions in header files is common practice. It is required if you wish to allow the compiler to inline function calls. If a function definition isn't visible at the **call site** the compiler cannot inline a function call. – IInspectable Nov 22 '13 at 15:20
0

If you have two files:

main.cpp

#include "func.h"

int main(){

    hello();

    std::cout<<" world!\n";

    return 0;
}

& func.h

#ifndef FUNC_H
#define FUNC_H

#include <iostream>

void hello(void){
    std::cout<<"hello";
}

#endif

iostreams objects and functions e.t.c will work fine from within main.cpp. This posts answers sum up #ifndef pretty well if you would like to know more.

Community
  • 1
  • 1
James
  • 1,009
  • 10
  • 11