Are static member functions in c++ copied in multiple translation units?
I have a helper class in my program which has many static functions used in different classes of my program. E.g.
helper.h
:
Class helper {
public:
static void fn1 ()
{ /* defined in header itself */ }
/* fn2 defined in src file helper.cpp */
static void fn2();
}
Helper has only static member functions. So, no objects of helper are created by other modules. Helper functions are used in other modules like:
A.cpp
#include "helper.h"
A::foo() {
helper::fn1();
helper::fn2();
}
B.cpp
#include "helper.h"
B::开发者_Python百科foo() {
helper::fn1();
helper::fn2();
}
Does the compiler create separate copies of helper functions in A.cpp
and B.cpp
? I read some earlier posts and I gathered from the replies that compiler will create so. But when I print the address of fn1
and fn2
as printf("Address of fn1 is %p\n", &helper::fn1);
and printf("Address of fn1 is %p\n", &helper::fn1);
from both A.cpp
and B.cpp
, I get the same address. I'm confused now. Can someone clarify, If I'm missing something.
The reason I'm worried about multiple copies of helper functions (if it happens) is we are trying to reduce our executable size and wanted to optimize it.
Functions defined inside the class body are implicitly marked inline
. If you take the address of the function, the compiler will also create a regular copy of the function (per compilation unit), but the linker will pick just one of these copies to include in the executable, so there's only one address.
However, the inlining process could make many copies of the function, even more than the number of compilation units. Often the increased size of duplicating the code is offset by the increased optimization possible by eliminating argument passing and function call overhead, as well as opportunities for common subexpression elimination, etc. Although inlining is often considered a tradeoff between size and speed, the size increase is often negligible or even negative.
The function that's just declared in the class and then implemented in a single compilation unit, definitely has just one copy in the executable.
if visible (e.g., defined in the class declaration), then it's implicitly declared inline by many compilers.
if inlined, then yes it may be copied in some cases, inlined in some cases, and partially inlined in other cases.
it follows the One Definition Rule (ODR), copies found in multiple translations will be removed when linked (unless you have enabled private extern inlines, then you could really end up with redundant exported implementations).
if you are coming from C: static does not create a unique copy of the function in this case -- it just means that you may call the function without an instance of the class which declares it.
An inlined static class method is not that different from an inlined free function. Theoretically the ODR rule means that there is a single instance of the function, but in practice the compiler may have always inlined it so that there is in fact no instance of the function per se.
However, the very act of taking the address of the function will force the compiler to create an instance of the function, and it is the compilation system's problem to enforce the ODR and hence ensure that you always get the same address.
精彩评论