27

I would like a function that is not a member of a class and is accessible from any class.

I assume I would have to #include the header file where the function is declared, but I don't know where to define such a global function.

Are there good reasons against having such a function in the first place?

Cory Klein
  • 51,188
  • 43
  • 183
  • 243

6 Answers6

37

you need a body (in a cpp file):

int foo()
{
    return 1;
}

and a definition/prototype in a header file, which will be included before any use of the function:

#ifndef MY_FOO_HEADER_
#define MY_FOO_HEADER_
    int foo();
#endif

then using it somewhere else:

#include foo.h
void do_some_work()
{
    int bar = foo();
}

or use an inline function (doesn't guarantee it'll be inlined, but useful for small functions, like foo):

#ifndef MY_FOO_HEADER_
#define MY_FOO_HEADER_
    inline int foo()
    {
        return 1;
    }
#endif

alternatively you can abuse the C-style header based functions (so this goes in a header, the static forces it to exist in a single compilation unit only, you should avoid this however):

#ifndef MY_FOO_HEADER_
#define MY_FOO_HEADER_
    static int foo()
    {
        return 1;
    }
#endif
MSalters
  • 173,980
  • 10
  • 155
  • 350
Necrolis
  • 25,836
  • 3
  • 63
  • 101
  • 4
    Why should you avoid using `static` to force the function to exist only in a single compilation unit? – HelloGoodbye May 16 '13 at 07:35
  • 1
    @HelloGoodbye: 'static' generally causes much confusion, esp. static global functions, this can lead to undesired behaviour or improper use, more importantly, if you are using C++, then you should code in C++, which means using a header with a prototype (which is possibly marked as extern) and a source file with the implementation, this also brings some useful side effects, thanks to the way headers are treated. – Necrolis May 16 '13 at 08:51
  • @Necrolis You saved me a lot of time from trouble. I was following [this link](http://stackoverflow.com/a/14909999/3458969) which had a lot longer and the same solution you gave. Yours is clear and concise. Appreciated – JohnJohn Jan 12 '15 at 20:26
  • @Necrolis : is it wrong to use the "extern" when the function has been declared and defined in another cpp-file but accessible? Or is this okay? "extern int foo();" It compiles perfectly, but your explanation makes much more sense :-) – Wim Aug 17 '15 at 14:56
  • @Wim: AFAIK the `extern` is superfluous except for templates (see C++11's extern template) – Necrolis Aug 17 '15 at 20:39
  • @Necrolis : thank you for the swift reply, I will correct it in my code :-) – Wim Aug 18 '15 at 12:23
8

What you are calling global function is usually called a free function and they are A Good Thing.

You would define it just like a class' member function, but outside of that class' scope.

double squared(double x) {
    return x*x;
}

Simple functions you can define with the inline keyword in the header file, or just declare it there

double squared(double x);

and put the implementation (first example) into the *.cpp file.

Benjamin Bannier
  • 55,163
  • 11
  • 60
  • 80
4

In a header file:

// someheader.h
#ifndef MY_GLOBAL_FUN
#define MY_GLOBAL_FUN

void my_global_fun();    

#endif

In an implementation file:

#include "someheader.h"

void my_global_fun()
{
    // ...
}

In other files that require that function:

#include "someheader.h"

void f()
{
    my_global_fun();
}

Free functions like this are useful and there are not many arguments against using them. Depending on your use case, its likely appropriate to put these functions in a specific namespace to avoid name collision with other libraries you may be using.

Chad
  • 18,706
  • 4
  • 46
  • 63
  • I'm still getting an Undefined symbols error for `my_global_fun()` and I've set up my files exactly how you've shown. Can you verify that this code worked for you? Of all of the answers on this subject on SO I find your to make the most sense. – Clay Ellis Sep 20 '15 at 16:47
  • There are a lot of reasons this can fail. What platform, compiler, and command (to build) are you using? – Chad Sep 21 '15 at 00:56
0

In addition to the answer by @Necrolis, the use of static is deprecated in favour of unnamed namespaces. However, use of unnamed namespaces and static both creates separate copies for each translation unit which increases the size of binary. The use of inline is better than both of these in this sense.

These solutions allow for more usage specific optimisations by compilers but are less instruction cache friendly compared to definition in a source file and then linking.

0

Think of main(). The function is kind of just...there. It's not within any class, struct or namespace. You just declare and give it a body. Of course, in the case of functions that are not main, it's best to put a prototype in a header and the define it in a .cpp file.

Remember, C did not have classes and structs could not hold member functions. There was nothing wrong with free functions then and there isn't now.

MGZero
  • 5,812
  • 5
  • 29
  • 46
0

You have to declare its prototype in header file and define it in implementation file.

//file.h
void foo();

//file.cpp
void foo ()
{}

To shortly answer your second question, Global functions are needed when they are used by several different classes and types in a generic way. For example math functions.

Otherwise, in general you may avoid so many global functions. Also you should avoid having a static local member or global data associated with such function (so that you don't have to worry about thread safety).

iammilind
  • 68,093
  • 33
  • 169
  • 336