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()
{
}
}
Related
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.
If I declare it in .h in obvious way:
namespace <named_namespace> {
namespace {
…
<type> <function>(<parameters>);
…
}
}
and put its implementation in .cpp, a compilation error will occur:
'<type> <named_namespace>::{anonymous}::<function>(<parameters>)' should have been declared inside <named_namespace>
Is it possible to avoid this error without putting the function's implementation in the single file? Currently I use keyword static instead, but it produces multiply annoying warnings:
'<type> <named_namespace>::<function>(<parameters>)' declared 'static' but never defined
which, as I've understood, can be disabled only by keeping function in a single file (header or source).
Cross-compiler solution is welcome (if any).
Or maybe splitting the header file into 'public' and 'private' parts is more efficient?
You cannot have anonymous namespace that works across translation units therefore putting anonymous namespace in .h won't work as you expect. In each translation unit (.cpp), that namespace is assigned a different, unique name.
Separated declaration and definition is possible but only inside that namespace:
namespace {
void func();
}
…
namespace {
void func()
{
…
}
}
I have functions stored with a class in a header file that I #include in the header of my Source.cpp file. The header contains a date class, along with relevant constructors, overloaded operators, and methods.
I leverage these functions in some of my class' constructors (for instance, a function to convert a Gregorian calendar day into a Julian day number). However, I can't think of a valid reason to allow the use of a few of these functions outside of the header file: they're only useful to the class, after all.
Is there a way for me to make it impossible for these functions to be called outside of the header file, short of making them private methods of my class?
EDIT: Would the solution also apply to other entities in the class, like structs?
What you are trying to achieve is materially difficult given the nature of header files in C++. Normally you hide internal details in a nested, anonymous namespace, however that would still be visible to callers who import your .h file. Thus you only use this trick inside of your .cpp file to make private, non-exported symbols.
The correct thing to do is to place these private class implementations and the implementation of your constructor inside of your .cpp file.
// foo.h
namespace fooproject {
class Foo {
public:
Foo(::string s);
private:
int converted_s; // Will be derived from constructor input
}
And then:
// foo.cpp
namespace {
// Everything here is visible to this compilation unit only.
int SecretMagicConverter(::string s) {
// magic code
}
} // namespace
namespace foo_project {
Foo::Foo(::string s) {
// Here we can plainly call the anonymous namespaced functions above.
converted_s = SecretMagicConverter(s);
}
} // namespace foo_project
Regarding your follow up, yes, anything in that anonymous namespace is 'normally' usable inside of that .cpp but hidden from any users of your .h 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
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.