putting function definitions in header files - c++

If you want to put function definitions in header files, it appears there are three different solutions:
mark the function as inline
mark the function as static
put the function in an anonymous namespace
(Until recently, I wasn't even aware of #1.) So what are the differences to these solutions, and when I should I prefer which? I'm in header-only world, so I really need the definitions in the header files.

The static and unnamed namespace versions end up being the same: each Translation Unit will contain it's own version of the function, and that means that given a static function f, the pointer &f will be different in each translation unit, and the program will contain N different versions of f (more code in the binary).
This is not the right approach to provide a function in a header, it will provide N different (exactly equal) functions. If the function contains static locals then there will be N different static local variables...
EDIT: To make this more explicit: if what you want is to provide the definition of a function in a header without breaking the One Definition Rule, the right approach is to make the function inline.

As far as I know, only inline and template functions can be defined in header files.
static functions are deprecated, and functions defined in an unnamed namespace should be used instead (see 7.3.1.1 p2). When you define a function in an unnamed namespace in a header, then every source code including that header (directly or indirectly) will have an unique definition (see 7.3.1.1 p1). Therefore, functions should not be defined in the unnamed namespace in header files (only in source files).
The standard referenced are from the c++03 standard.
EDIT:
Next example demonstrates why functions and variables shouldn't be defined into unnamed namespace in headers :
ops.hpp contains:
#ifndef OPS_HPP
#define OPS_HPP
namespace
{
int a;
}
#endif
dk1.hpp contains:
#ifndef DK1_HPP
#define DK1_HPP
void setValue();
void printValue();
#endif
dk1.cpp contains:
#include "dk1.hpp"
#include "ops.hpp"
#include <iostream>
void setValue()
{
a=5;
}
void printValue()
{
std::cout<<a<<std::endl;
}
dk.cpp contains :
#include "dk1.hpp"
#include "ops.hpp"
#include <iostream>
int main()
{
// set and print a
setValue();
printValue();
// set and print it again
a = 22;
std::cout<<a<<std::endl;
// print it again
printValue();
}
Compile like this:
g++ -ansi -pedantic -Wall -Wextra dk.cpp dk1.cpp
and the output :
5
22
5
ops the variable a is different for the source file dk1.cpp and dk.cpp

static functions (equivalent to anonymous namespace) receive different copies for each TU. If the function is re-entrant this is basically identical (some compilers might have assembly-level differences) but if it isn't then it will have different static data for each TU. Inline functions are folded- that is, they have only one copy of static data for every TU.

You could consider wrapping the methods in a class instead of a namespace. Declare these methods as static and delete the constructor of the class to reinforce that this is not an object to be instantiated.
struct FooNamespace
{
FooNamespace() = delete;
static FooMethod1() {
...
}
static FooMethod2() {
...
}
};
You get the same general behavior as it belonging to a namespace with only a single implementation.

Related

how to define global variable without causing multiple declaration of same variable problem?

I have the following definition of a global variable in a header that was included in several cpp file. I do have the #pragma once included.
// A.h // only declarations and variable definition here.
#pragma once
int i = 1;
class one{public: one(); int j, p=1;};
class two{public: two(); int m, q=10;};
// B.cpp // definition of class one methods
#include "A.h"
one::one(){j=i;}
// C.cpp // definition of class two methods
#include "A.h"
two::two(){m=i;}
// D.cpp
#include "A.h"
int main()
{
one b();
two a();
}
when compiling the compiler returns two error that both say int i has been defined in D.obj.
Several problems in your code (some maybe be typos you made while writing the question)
you include headers, whereas you should #include them;
main has to have a return value type of int;
you declare classes, so without you writing public: before members, they are private by default; this results in a private constructor, for instance; you better write classes in a more readable way, by the way:
class one {
public:
one();
private:
int j;
int p = 1;
};
when declaring a and b in main, you should guard against MVP; one way to do so is writing one b{}; and two a{}; instead.
it's good practice putting #pragma once at the top of the headers so that they don't get included more than once in each translation unit;
furthermore, when you define a variable in a header file, each cpp file including the header will have its own version of that variable; you need to inline those variables; from here you can read that (my emphasis)
An inline function or inline variable (since C++17) has the following properties:
...
An inline function or variable (since C++17) with external linkage (e.g. not declared static) has the following additional properties:
There may be more than one definition of an inline function or variable (since C++17) in the program as long as each definition appears in a different translation unit and (for non-static inline functions and variables (since C++17)) all definitions are identical. For example, an inline function or an inline variable (since C++17) may be defined in a header file that is #include'd in multiple source files.

How can you access the function from another translation unit without including any files?

I was reading about static functions and it was said that if the function is static then you can use it only in the same file. After testing it, I realized it is not true because if you include the file with a static function you can still use that function in another file. Then I read a clarification that you can actually use static function only in the same translation unit. Ok, that makes sense because it means .cpp + includes, but even if the function is not static, you will still not be able to use it unless you include the file. So how is it even possible to access a function from another translation unit in the first place without including anything, what is the point of static functions?
Main.cpp
#include "Staticf.h"
void main()
{
visible();
}
Staticf.h
#pragma once
#include <iostream>
using namespace std;
static void visible()
{
cout << "Static function is visible\n";
}
This compiles alright. If I make that function non-static and remove #include "Staticf.h" I will not be able to use it in Main anyways. So why are static functions needed if you can't access non-static as well?
You can access non-static functions from other translation units. You just need a forward declaration:
somemodule.cpp
void func()
{
// details
}
main.cpp
void func();
int main()
{
func();
}
It is, of course, a best practice to put the forward declaration in a header file.
So what use are static functions?
In modern C++, they actually aren't much use. static is a feature C++ inherited from C. In C, declaring a helper function static is actually pretty useful because C doesn't have namespaces. You can use static to eliminate the chance of name collisions between your private helper functions and the private helper functions in other translation units. In C++, it's generally preferred to wrap your private helpers in a class or anonymous namespace.
If the function is static (as if free static function), you cannot access it from another translation unit.
Remove the static, and if you can't include a header (you probably can though... change the former static function's header), add a prototype in the file.

Is there "static class" in C++ like a static function meant to be accessed within the same file?

I understand that static function declarations are done at the top of .cpp files such that I can use it only within that file and compiler would not complain if there are functions in other files with the same name. Is there an equivalent for classes? That is, declaring a "private" class used only within that file.
First, the C++ specification does not refer to source code files.
The relevant unit here is a translation unit, also called a compilation unit, and in practical terms it consists of all the source code resulting from preprocessing of an implementation file.
So you can have internal linkage (a.k.a. static) functions in any kind of file. Although it doesn't make much practical sense to have them in a header file. Also, the placement in the code, whether first or last, does not matter.
An alternative to an internal linkage function like
static void foo() {}
is to place the function in an anonymous namespace, like
namespace {
void foo() {}
} // namespace <anon>
and you can do that also for a class.
Effectively this is equivalent to
namespace very_unique_autogenerated_name {
void foo() {}
}
// And in global namespace:
using namespace very_unique_autogenerated_name;
which means that you can refer to things in the anonymous namespace as if they were in the global namespace, and that you can have external linkage things there without their names colliding with other things in anonymous namespaces in other translation units.
XY problem? You can have classes with the same name in different files, unless you link them together. If your problem is that you have a name conflict, you can resolve that using namespaces:
//file1.cpp
namespace file1 {
class A { .. };
}
//file2.cpp
namespace file2 {
class A { .. }; //compiler won't complain
}
You can use unnamed namespaces for this:
namespace {
class A {};
}
There is more discussion at Unnamed/anonymous namespaces vs. static functions

The function extension in C++ definition file (CPP)

In C++ definition file (.cpp), sometimes I can define small functions to be invoked, for example:
// Class declaration
// Myclass.h
Class Myclass
{
...
void Classfunction();
...
}
// Class defination
// Myclass.cpp
#include "Myclass.h"
...
void helper_fun()
{
...
}
...
void Myclass::Classfunction()
{
...
helper_fun();
...
}
In the above example, we can see void helper_fun() is declared and defined in the .cpp file. The purpose of this function is to be invoked by the functions that have been defined in the class. Of course, the helper_fun can be declared in the head file first and then defined in the implementation file. My question is whether this is a good practice for C++ code writing. Moreover, does this practice have some bad effects? Thanks!
It would be good practice to have the helper_fun defined in an anonymous namespace within the source file.
Like this:
namespace {
void helper_fun()
{
//...
}
}
Reason being that if another helper_fun is defined in another source file with the same signature, you wouldn't have any risk with linkage errors. It's not to say that there will be, but rather, there could be one.
Also, you shouldn't put functions in your header if it's not going to be used outside of the respective source file.
Having local helper functions in the source files are very common. Normally they are either declared as static (e.g. static void helper_fun() { }) or in an anonymous namespace (e.g. namespace { void helper_fun() { } }).
Making the functions static or having them in an anonymous namespace is so that they wont be callable from the outside, and so that you can have more local functions with the same name.
If, however, you want to call the function from other source files, then define the function normally, and add a declaration in the header file.
If you need it to be public, and included in other files via the header file. Then put it there.
Otherwise there's no reason for it to be in the header.
If you declare helper_fun in the header, it becomes visible to users of Myclass.h. Do you want helper_fun to be used elsewhere?
By keeping it solely within Myclass.cpp you ensure it can only be used by code within Myclass.cpp.
Of course declare functions in .cpp files is ok. It is helper function, so, you shouldn't give its declaration to user. You can use anonymous namespace for internal linkage (by default functions has external linkage).
An unnamed namespace or a namespace declared directly or indirectly
within an unnamed namespace has internal linkage.
like this
namespace
{
// helper_fun has internal linkage.
void helper_fun()
{
}
}

How do you define a global function in C++?

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