I have a static constexpr member function that i declare in the .h file. If i define the function right away in the header file, everything works perfectly. I have the general inclination to define functions in the .cpp file (even if i want them inlined, i would use the inline keyword and again do so) so i when i try to do it, it seems okay at first but when i try to call this function i get the following error:
static constexpr uint16_t ClassA::myFoo()' used before its definition
I would like learn if there is a way to define a static constexpr member function in the .cpp file rather than the header. If thats not possible or maybe limited due the compiler i am using, is there any side effects defining the function in the .h file ? (I know it is explicitly inline for normal functions but i am not sure for a constexper static function).
PS: I am using arm-none-eabi-g++ (c++17) and Clion for a small embedded project.
I would like learn if there is a way to define a static constexpr member function in the .cpp file rather than the header.
Yes... but you must define the function in every TU where it is used because it is an inline function. As such, it is simpler to put the definition into a header so that same definition will be included into all the TUs that need it.
It is an inline function because constexpr functions are implicitly inline functions - i.e. whether or not you use the inline keyword.
is there any side effects defining the function in the .h file ?
The effect of doing this is that the function definition will be included into every TU that include the header. I don't quite understand what you mean by "side" effect in this context.
Related
I have a very small function that could be a macro, but anyway, I thought inline function would do exactly the same.
But nah, when I mark a function in a namespace as inline it is not visible by any other file that includes my module.
I tried it both with a static class and a namespace. No error when the function is declared or implemented, error in each reference, exactly as if the function was static.
Is there a way to have an inline function available for other files that include the file where my function is declared?
Let's say I have a module that handles some hardware stuff, and one of the functions is something like this:
bool getState(HWFlag flag)
{
return (State & flag) > 0
}
I know, it can be written as macro, but logically the function is a part of a bigger module. I would certainly used a macro in C, but it's C++ so I thought there might be a better way. But well, I obviously don't understand how it works.
BTW, shouldn't the compiler just inline it anyway so I shouldn't even care?
BTW2: Is making the module that mainly talks with C code a class with only static method a bad idea or does it have any use? That's how I made it initially but later decided to just make it a namespace to simplify the syntax a little. But in any case, if I use the inline keyword the function becomes private.
An inline function should be defined identically in every translation unit that uses it. So you should define your inline function exactly as you would a macro--in a header file that gets included by all of the files that need it.
in header file:
inline void func(void); // declare only, with `inline`
in impl source file:
void func(void) { balabala(); }
in other source file:
func(); // call the func
Question: Is it legal to declare inline function, even if it's not actually inlined in header file?
PS:
Why need this: I have some macro generated functions, may or may not be declare in header only, so I wish the macro can be used without explicitly specify inline or not
And, I know the function can be wrapped by a wrapper class as static member function in header
the tricky inline solution was tested under MSVC and clang without compile error, simply want to know whether it's legal in C++ standard
It's not legal. From cppreference.com:
2) The definition of an inline function or variable (since C++17) must
be present in the translation unit where it is accessed (not
necessarily before the point of access).
Whether or not it's legal I'm not sure how useful it is. Inline functions must be defined in the same translation units where they're used. That is, the second file should give a linker error because you only defined it in the impl file.
[dcl.inline]
An inline function or variable shall be defined in every translation unit in which it is odr-used and shall have exactly the same definition in every case ([basic.def.odr]).
If your compiler does LTO (or GL) you might get away with it, otherwise unless you're redefining the same inline function in every TU (or just using it in a single one), this is not legal.
I know that the inline keyword is only a hint for the compiler, and not forced (unless using __forceinline e.g. in MSVC).
Is it also the case when declaring the inlined function in header? In which compilation unit will the compiler put the code?
inline is not just a hint to the compiler.
An inline function may be defined in multiple translation units, and all of these definitions will have the same type, address, and definition.
If a function is defined in a header, then it must be declared inline, or it will violate the One Definition Rule when it is included in multiple translation units.
An inline function is either:
A function at global scope can be declared inline using the keyword inline.
A function defined entirely inside a class/struct/union definition, whether it's a member function or a non-member friend function, is always inline.
A function declared constexpr is always inline.
(source)
Is it also the case [that inline is a hint] when declaring the inlined function in header?
Yes. The inline keyword is always a hint to the compiler to perform "inlining".
However, please note that this is only a hint. The compiler is free to ignore it (and many do).
The real reason compilers are able to perform inlining on inline functions is that the whole definition is available. You will notice the same inlining with static functions and instantiated function templates.
In which compilation unit will the compiler put the code?
Before linkage, the inline function will be fully defined in any compilation unit that defines it. It will be compiled in its entirety into each object file.
During linkage, the linker will determine which definition to use, and discard all the others.
See also this question and its answers.
The code will be present in all compillation units that include this header. The main point of inline is saying to the linker that this function can be found in multiple object files and any of these copies can be chosen by linker.
Inline is not forced, ever. If you define a method inside the class definition, it is implicitly inlined. It's like defining it outside the class definition except with inline implied. This has nothing to do with what file the definition is in.
When a function you requested to inline is not actually inlined, it's up to the compiler to decide where to put it. In early days, you could get a non-exported copy in each file that header file was included in. Now, some strategy is applied like putting it in the same place as the first constructor, the first method, or where the virtual function table is. It's compiler-dependent.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Inline functions in C++
What does the compiler do if I completely implement a class in its header file? A typical example follows:
class MyException
{
public:
explicit MyException(const char* file, int line) file(file), line(line) {};
const char* getFile() const { return file };
int getLine() const { return line };
private:
const char* const file;
const int line;
};
My intention is to use the class like this: throw MyException(__FILE__, __LINE__).
I include this header file into each .cpp file. I suppose the compiler will compile the class as many times as it is defined and include the (identical) machine code into every object file it produces. Now, what will the linker do? I tried a simpler example (without all those pesky const's) and it compiled fine.
What would happen, if instead of a simple class, I implemented a three-screenful-long C function in a header file? And the final question, should I split my example into .h and .cpp files?
All methods will be inline methods. You may loose some minimal time on the overall compilation, but it's ok. As far as I know the only problem that can occur is if you have a static non-cost member variable. Then you have to assign a storage place for it (place a definition and and initial value if you want) presumably in a .cpp or else you will get linker errors about multiple definition.
I've seen header-only projects which had only the main() function in a CPP, but that was heavily templated.
Update for C++17: You can declare static non-const members as inline in your header file since C++17. This makes header-only libraries easily possible without gymnastics like static variables inside inline functions.
A class definition itself doesn't produce any code. It just shows users of the class how it is layed out, so they can generate appropriate code to manipulate it.
It's the member functions of the class that generate code. When you define a member function inside the class definition it gives the function an implicit inline declaration.
A function call can be compiled and linked in one of two ways:
(1) A single copy of the function code with a RETURN assembly instruction at the end can be placed in the image, and a CALL assembly instruction can be placed (along with param passing and return value transfer) at the call site to transfer control to this code.
or
(2) An entire copy of the function implementation can replace the entire function call at the call site.
A function declared inline is a recommendation to the compiler to do it the second way. Further an inline declaration allows the function to be defined in several translation units (so it can be placed in a shared header file). In order for the compiler have the option of implementing the second method, it needs a copy of the function implementation at compile-time. This isn't available if the function implementation is in a foreign translation unit.
It should also be noted that modern compilers do complicated things with functions declared inline. See:
http://gcc.gnu.org/onlinedocs/gcc/Inline.html
When you implement member functions inside a header file, all those functions become implicitly inline.
What does this mean and what implications does it have?
As per,
C++03 Standard ยง7.1.3/4:
It hints the compiler that substitution of function body at the point of call is preferable over the usual function call mechanism.
Even if the inline substitution is omitted, the other rules(especially w.r.t One Definition Rule) for inline are followed.
So Yes, every translation unit will have the definition of the inline function.This may result in increase in the size of your binaries.
Usually any good mainstream compiler will substitute function body at the point of call if needed, so marking functions inline merely for #1 is not really a good idea but if you want to make your intent clear to users of your class then you can do so by defining the functions within the header or explicitly marking your functions as inline.
Should I split my example into .h and .cpp files?
Yes, that is the usual compilation model that most of the projects use, wherein you separate the interface(.h) from the implementation(.cpp).The interfaces are shared with the users of your code as header files while the implementation is provided in the form of binaries.To some extent this provides a safeguard to your intellectual property.
This is known as the Separation Model.
C++ projects using templates will usually use the Inclusion Model rather than the Separation Model of usual C++ projects.
code from google's v8 js engine, allocation.h:
template <typename T>
static void DeleteArray(T* array) {
delete[] array;
}
This is a function template (top level, not in any class).
But what the static keyword is for?
That it's a template is actually a side-issue.
It being static means the function is not visible outside of the file (but since it's in a header and headers are effectively part of the files that include them, that means outside of the file that includes the header; and each file that includes the header effectively has its own, identical but private version of the function).
From http://msdn.microsoft.com/en-us/library/s1sb61xd%28VS.80%29.aspx:
"When modifying a variable or function
at file scope, the static keyword
specifies that the variable or
function has internal linkage (its
name is not visible from outside the
file in which it is declared)."
See here fore more on what it means to have this in a header file:
C/C++: Static function in header file, what does it mean?
The static keyword gives the definition "internal linkage", which means it would be legal to give the name DeleteArray another meaning or a different definition in a different source file. (Just as is the case with static void f(); or static int i;.) But I can't imagine anyone would want to do that.
Use of static this way in C++ is deprecated. This declaration would probably be better without the static keyword, making it implicitly extern (and still inline). In that case, the linker would be allowed to combine any definitions of DeleteArray<T>(T*) for the same T from multiple objects, since they would be the same thing.
static functions (outside of a class) cannot be used outside the defining file. It's a holdover from C where there are no namespaces. I bet you'll find that DeleteArray() isn't called from another file, unless it's been redefined in that other file.