Extern for class method - c++

I want to use extern keyword for class method in C++. I'm using Visual Studio 2019.
I want to force method inline, using __forceinline(without extern I will get unresolved external symbol). I don't want to put method implementation in this header file, I want put implementation in other .cpp file.
I noticed that method may be inlined automaticly without extern and __forceinline and when method's implementation in .cpp file. How can I force it?
Example code:
class Window {
public:
void Show();
};
That's ok!
class Window {
public:
__forceinline void Show();
};
Gets unresolved external symbol when I calls this function from other CPP.
With extern I gets:
screenshot
For simple functions extern __forceinline works fine:
screenshot

You cannot specify extern for a member function.
The standard clarifies this in [dcl.stc]/5:
The extern specifier can be applied only to the names of variables and functions. The extern specifier cannot be used in the declaration of class members or function parameters.
When you use extern, you say to the compiler that you declare a variable or a function, but without defining it. In the case of member functions, this is not needed: they can always be declared in a class body without being defined:
class A {
public:
void f(); // you can define it in which ever compilation unit (cpp) you want
};
...
// Else where...may be in another cpp
void A::f() {...}
The linker will resolve the symbols when needed.
The inline is not so useful
The standard in [dcl.inline]/2 says that inline is not guaranteed:
The inline specifier indicates to the implementation that inline
substitution of the function body at the point of call is to be
preferred to the usual function call mechanism. An implementation is
not required to perform this inline substitution at the point of call;
Furthermore, [dcl.inline]/6 explains that inline and defined eleswhere is not something meant to work well:
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.
(odr says that all the definitions must be exactly the same definition each time)
(in every translation unit means in every cpp or the headers therein included)
On the other side, the global optimizer of some modern compilers is able to achieve similar performance effects than inlined functions, and this accross compilation units (cpp).
Implementation specific forceinline
MSVC 2019 uses inline carefully, making a cost/benefit analysis to decide whether or not to inline.
forceinline allows you to overrule the compiler's judgement. But it comes with all the requirements of the normal inline: so you need to have a definition of the function in the same compilation unit to get it work.

Two things:
You cannot declare a member function as extern. These already have external linkage.
For the compiler to inline a function or method, it has to be defined (as opposed to declared) in the header file. This is so that the compiler can see it when compiling code that calls the function.
So, just put the function body in the header file and drop the extern.

I don't want to put method implementation in this header file, I want put implementation in other .cpp file.
Sounds to me like you just want to have all declarations in one file like this:
This is your window.h- file:
class Window
{
public:
void Show();
};
To have the implementation in another file, you have to use the scope operator.
This is the other window.cpp- file, in which you have the actual implementation of the function:
#include "window.h"
Window::Show()
{
// Your implementation goes here
}
I hope I understood your question right and this helps.

Related

Duplicate symbol while invoking headers from mainwindow.h [duplicate]

Ok, not a C/C++ expert by any means, but I thought the point of a header file was to declare the functions, then the C/CPP file was to define the implementation.
However, reviewing some C++ code tonight, I found this in a class's header file...
public:
UInt32 GetNumberChannels() const { return _numberChannels; } // <-- Huh??
private:
UInt32 _numberChannels;
So why is there an implementation in a header? Does it have to do with the const keyword? Does that inline a class method? What exactly is the benefit/point of doing it this way vs. defining the implementation in the CPP file?
Ok, not a C/C++ expert by any means, but I thought the point of a header file was to declare the functions, then the C/CPP file was to define the implementation.
The true purpose of a header file is to share code amongst multiple source files. It is commonly used to separate declarations from implementations for better code management, but that is not a requirement. It is possible to write code that does not rely on header files, and it is possible to write code that is made up of just header files (the STL and Boost libraries are good examples of that). Remember, when the preprocessor encounters an #include statement, it replaces the statement with the contents of the file being referenced, then the compiler only sees the completed pre-processed code.
So, for example, if you have the following files:
Foo.h:
#ifndef FooH
#define FooH
class Foo
{
public:
UInt32 GetNumberChannels() const;
private:
UInt32 _numberChannels;
};
#endif
Foo.cpp:
#include "Foo.h"
UInt32 Foo::GetNumberChannels() const
{
return _numberChannels;
}
Bar.cpp:
#include "Foo.h"
Foo f;
UInt32 chans = f.GetNumberChannels();
The preprocessor parses Foo.cpp and Bar.cpp separately and produces the following code that the compiler then parses:
Foo.cpp:
class Foo
{
public:
UInt32 GetNumberChannels() const;
private:
UInt32 _numberChannels;
};
UInt32 Foo::GetNumberChannels() const
{
return _numberChannels;
}
Bar.cpp:
class Foo
{
public:
UInt32 GetNumberChannels() const;
private:
UInt32 _numberChannels;
};
Foo f;
UInt32 chans = f.GetNumberChannels();
Bar.cpp compiles into Bar.obj and contains a reference to call into Foo::GetNumberChannels(). Foo.cpp compiles into Foo.obj and contains the actual implementation of Foo::GetNumberChannels(). After compiling, the linker then matches up the .obj files and links them together to produce the final executable.
So why is there an implementation in a header?
By including the method implementation inside the method declaration, it is being implicitly declared as inlined (there is an actual inline keyword that can be explicitly used as well). Indicating that the compiler should inline a function is only a hint which does not guarantee that the function will actually get inlined. But if it does, then wherever the inlined function is called from, the contents of the function are copied directly into the call site, instead of generating a CALL statement to jump into the function and jump back to the caller upon exiting. The compiler can then take the surrounding code into account and optimize the copied code further, if possible.
Does it have to do with the const keyword?
No. The const keyword merely indicates to the compiler that the method will not alter the state of the object it is being called on at runtime.
What exactly is the benefit/point of doing it this way vs. defining the implementation in the CPP file?
When used effectively, it allows the compiler to usually produce faster and better optimized machine code.
It is perfectly valid to have an implementation of a function in a header file. The only issue with this is breaking the one-definition-rule. That is, if you include the header from multiple other files, you will get a compiler error.
However, there is one exception. If you declare a function to be inline, it is exempt from the one-definition-rule. This is what is happening here, since member functions defined inside a class definition are implicitly inline.
Inline itself is a hint to the compiler that a function may be a good candidate for inlining. That is, expanding any call to it into the definition of the function, rather than a simple function call. This is an optimization which trades the size of the generated file for faster code. In modern compilers, providing this inlining hint for a function is mostly ignored, except for the effects it has on the one-definition-rule. Also, a compiler is always free to inline any function it sees fit, even if it has not been declared inline (explicitly or implicitly).
In your example, the use of const after the argument list signals that the member function does not modify the object on which it is called. In practice, this means that the object pointed to by this, and by extension all class members, will be considered const. That is, trying to modify them will generate a compile-time error.
It is implicitly declared inline by virtue of being a member function defined within the class declaration. This does not mean the compiler has to inline it, but it means you won't break the one definition rule. It is completely unrelated to const*. It is also unrelated to the length and complexity of the function.
If it were a non-member function, then you would have to explicitly declare it as inline:
inline void foo() { std::cout << "foo!\n"; }
* See here for more on const at the end of a member function.
Even in plain C, it is possible to put code in a header file. If you do it, you usually need to declare it static or else multiple .c files including the same header will cause a "multiply defined function" error.
The preprocessor textually includes an include file, so the code in an include file becomes part of the source file (at least from the compiler's point of view).
The designers of C++ wanted to enable object-oriented programming with good data hiding, so they expected to see lots of getter and setter functions. They didn't want an unreasonable performance penalty. So, they designed C++ so that the getters and setters could not only be declared in the header but actually implemented, so they would inline. That function you showed is a getter, and when that C++ code is compiled, there won't be any function call; code to fetch out that value will just be compiled in place.
It is possible to make a computer language that doesn't have the header file/source file distinction, but just has actual "modules" that the compiler understands. (C++ didn't do that; they just built on top of the successful C model of source files and textually included header files.) If source files are modules, it would be possible for a compiler to pull code out of the module and then inline that code. But the way C++ did it is simpler to implement.
As far as I know, there are two kinds of methods, which can be safely implemented inside the header file.
Inline methods - their implementation is copied to places, where they are used, so there is no problem with double-definition linker errors;
Template methods - they are actually compiled at the moment of template instantiation (eg. when someone inputs a type in place of template), so again there is no possibility of double-definition problem.
I believe, your example fits the first case.
C++ standard quotes
The C++17 N4659 standard draft 10.1.6
"The inline specifier" says that methods are implicitly inline:
4 A function defined within a class definition is an inline function.
and then further down we see that inline methods not only can, but must be defined on all translation units:
6 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 (6.2).
This is also explicitly mentioned in a note at 12.2.1 "Member functions":
1 A member function may be defined (11.4) in its class definition, in which case it is an inline member function (10.1.6) [...]
3 [ Note: There can be at most one definition of a non-inline member function in a program. There may be
more than one inline member function definition in a program. See 6.2 and 10.1.6. — end note ]
GCC 8.3 implementation
main.cpp
struct MyClass {
void myMethod() {}
};
int main() {
MyClass().myMethod();
}
Compile and view symbols:
g++ -c main.cpp
nm -C main.o
output:
U _GLOBAL_OFFSET_TABLE_
0000000000000000 W MyClass::myMethod()
U __stack_chk_fail
0000000000000000 T main
then we see from man nm that the MyClass::myMethod symbol is marked as weak on the ELF object files, which implies that it can appear on multiple object files:
"W"
"w" The symbol is a weak symbol that has not been specifically tagged as a weak object symbol. When a weak defined symbol is linked with a normal defined symbol, the normal defined symbol is used with no error. When a weak undefined symbol is linked
and the symbol is not defined, the value of the symbol is determined in a system-specific manner without error. On some systems, uppercase indicates that a default value has been specified.
Keeping the implementation in the class header file works, as I'm sure you know if you compiled your code. The const keyword ensures you don't change any members, it keeps the instance immutable for the duration of the method call.

is it legal to declare inline but not actually inline a function in C++

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.

Why defining classes in header files works but not functions

I have this little piece of code :
File modA.h
#ifndef MODA
#define MODA
class CAdd {
public:
CAdd(int a, int b) : result_(a + b) { }
int getResult() const { return result_; }
private:
int result_;
};
/*
int add(int a, int b) {
return a + b;
}
*/
#end
File calc.cpp
#include "modA.h"
void doSomeCalc() {
//int r = add(1, 2);
int r = CAdd(1, 2).getResult();
}
File main.cpp
#include "modA.h"
int main() {
//int r = add(1, 2);
int r = CAdd(1, 2).getResult();
return 0;
}
If I understand well, we can't define a function in a header file and use it in different unit translations (unless the function is declared static). The macro MODA wouldn't be defined in each unit translation and thus the body guard wouldn't prevent the header from being copied in place of every #include "modA.h". This would cause the function to be defined at different places and the linker would complain about it. Is it correct ?
But then why is it possible to do so with a class and also with methods of a class. Why doesn't the linker complain about it ?
Isn't it a redefinition of a class ?
Thank you
When member functions are defined in the body of the class definition, they are inline by default. If you qualify the non-member functions inline in the .h file, it will work fine.
Without the inline qualifier, non-member functions defined in .h files are compiled in every .cpp file that the .h file is included in. That violates the following rule from the standard:
3.2 One definition rule
3 Every program shall contain exactly one definition of every non-inline function or variable that is odr-used in that program; ...
You will get the same error if you define member functions outside the body of the class definition in a .h file and did not add the inline qualifier explicitly.
Multiple translation units might need the definition of the class at compile time since it is not possible to know, for example, the types of members of the class (or even whether they exist) unless the definition of the class is available. (Therefore, you must be allowed to define a class in multiple translation units.) On the other hand, a translation unit only needs the declaration of a function because as long as it knows how to call the function, the compiler can leave the job of inserting the actual address of the function to the linker.
But this comes at a price: if a class is defined multiple times in a program, all the definitions must be identical, and if they're not, then you may get strange linker errors, or if the program links, it will probably segfault.
For functions you don't have this problem. If the function is defined multiple times, the linker will let you know. This is good, because it avoids accidentally defining multiple functions with the same name and signature in a given program. If you want to override this, you can declare the function inline. Then the same rule as that for classes applies: the function has to be defined in each translation unit in which it's used in a certain way (odr-used, to be precise) and all the definitions must be identical.
If a function is defined within a class definition, there's a special rule that it's implicitly inline. If this were not the case, then it would make it impossible to have multiple definitions of a class as long as there's at least one function defined in the class definition unless you went to the trouble of marking all such functions inline.
” If I understand well, we can't define a function in a header file and use it in different unit translations (unless the function is declared static)
That's incorrect. You can, and in the presented code CAdd::getResult is one such function.
In order to support general use of a header in multiple translation units, which gives multiple competing definitions of the function, it needs to be inline. A function defined in the class definition, like getResult, is automatically inline. A function defined outside the class definition needs to be explicitly declared inline.
In practical terms the inline specifier tells the linker to just arbitrarily select one of the definitions, if there are several.
There is unfortunately no simple syntax to do the same for data. That is, data can't just be declared as inline. However, there is an exemption for static data members of class templates, and also an inline function with extern linkage can contain static local variables, and so compilers are required to support effectively the same mechanism also for data.
An inline function has extern linkage by default. Since inline also serves as an optimization hint it's possible to have an inline static function. For the case of the default extern linkage, be aware that the standard then requires the function to be defined, identically, in every translation unit where it's used.
The part of the standard dealing with this is called the One Definition Rule, usually abbreviated as the ODR.
In C++11 the ODR is §3.2 “One definition rule”. Specifically, C++11 §3.2/3 specifies the requirement about definitions of an inline function in every relevant translation unit. This requirement is however repeated in C+11 §7.1.2/4 about “Function specifiers”.

Undefined reference when inline specifier used with class member [duplicate]

This question already has answers here:
C++ inlining class methods causes undefined reference
(3 answers)
Closed 1 year ago.
I have some member functions in a class. When I use the inline specifier, the compiler complains of undefined reference.
I have tried:
Using 'inline' to precede the function definition in the class header file only.
Using 'inline' to precede the function declaration in the class .cpp (where the member functions are specified) file only.
Doing both of the above at the same time.
Obviously, one of these ways is the correct thing to do, and the others are not correct. However trying each option did not get me a program which compiled.
Here is what I am trying to do:
.hpp file:
class A{
void func();
}
.cpp file:
... include ...
inline void A::func()
{
...
}
Or maybe 'inline' goes elsewhere. I have tried all possible combinations I could think of, as I explained above. (Now watch someone tell me I need it AFTER the function name and arguments, like the keyword 'const'.)
Anyone any ideas on what I am doing wrong? I tried googling what the correct answer might be, but no luck. Are 'inline' functions inside a class even a thing?
Inline functions have to be defined in header files. The definition (the body) of the function has to be visible in all translation units that attempt to use that function. You can define it directly inside the class. Or you can define it as in your code, i.e. outside of the class. But it has to be in header file, not in .cpp file.
Attempting to define an inline function in .cpp file will make it usable in that .cpp file only. Trying to use it in other .cpp files will lead to linker errors (i.e. "undefined reference" errors).
Putting inline anything inside the CPP file can only possibly inline the function inside that file. If you want to encourage the compiler to inline the function, you need to forget about the CPP file. Instead, do this in the hpp file:
class A{
inline void func();
};
void A::func() {...}
NB a few points:
Putting inline doesn't mean your function will be inlined. It's a hint to the compiler.
You need optimization (-O3 in gcc) to even have a chance at it being inlined
If you define the function inside the class, it implicitly has the inline keyword on:
class A{
inline void func() {
...
}
};
is the same as the above where it was declared inline in the class and the definition was outside.
There are ways to force GCC to inline your code using function attributes, but I will not describe them because it is rarely a good idea to use them. GCC should do the "best" thing regarding inlining for each function. Forcing it to do something else will almost always result in worse performance.

How can a C++ header file include implementation?

Ok, not a C/C++ expert by any means, but I thought the point of a header file was to declare the functions, then the C/CPP file was to define the implementation.
However, reviewing some C++ code tonight, I found this in a class's header file...
public:
UInt32 GetNumberChannels() const { return _numberChannels; } // <-- Huh??
private:
UInt32 _numberChannels;
So why is there an implementation in a header? Does it have to do with the const keyword? Does that inline a class method? What exactly is the benefit/point of doing it this way vs. defining the implementation in the CPP file?
Ok, not a C/C++ expert by any means, but I thought the point of a header file was to declare the functions, then the C/CPP file was to define the implementation.
The true purpose of a header file is to share code amongst multiple source files. It is commonly used to separate declarations from implementations for better code management, but that is not a requirement. It is possible to write code that does not rely on header files, and it is possible to write code that is made up of just header files (the STL and Boost libraries are good examples of that). Remember, when the preprocessor encounters an #include statement, it replaces the statement with the contents of the file being referenced, then the compiler only sees the completed pre-processed code.
So, for example, if you have the following files:
Foo.h:
#ifndef FooH
#define FooH
class Foo
{
public:
UInt32 GetNumberChannels() const;
private:
UInt32 _numberChannels;
};
#endif
Foo.cpp:
#include "Foo.h"
UInt32 Foo::GetNumberChannels() const
{
return _numberChannels;
}
Bar.cpp:
#include "Foo.h"
Foo f;
UInt32 chans = f.GetNumberChannels();
The preprocessor parses Foo.cpp and Bar.cpp separately and produces the following code that the compiler then parses:
Foo.cpp:
class Foo
{
public:
UInt32 GetNumberChannels() const;
private:
UInt32 _numberChannels;
};
UInt32 Foo::GetNumberChannels() const
{
return _numberChannels;
}
Bar.cpp:
class Foo
{
public:
UInt32 GetNumberChannels() const;
private:
UInt32 _numberChannels;
};
Foo f;
UInt32 chans = f.GetNumberChannels();
Bar.cpp compiles into Bar.obj and contains a reference to call into Foo::GetNumberChannels(). Foo.cpp compiles into Foo.obj and contains the actual implementation of Foo::GetNumberChannels(). After compiling, the linker then matches up the .obj files and links them together to produce the final executable.
So why is there an implementation in a header?
By including the method implementation inside the method declaration, it is being implicitly declared as inlined (there is an actual inline keyword that can be explicitly used as well). Indicating that the compiler should inline a function is only a hint which does not guarantee that the function will actually get inlined. But if it does, then wherever the inlined function is called from, the contents of the function are copied directly into the call site, instead of generating a CALL statement to jump into the function and jump back to the caller upon exiting. The compiler can then take the surrounding code into account and optimize the copied code further, if possible.
Does it have to do with the const keyword?
No. The const keyword merely indicates to the compiler that the method will not alter the state of the object it is being called on at runtime.
What exactly is the benefit/point of doing it this way vs. defining the implementation in the CPP file?
When used effectively, it allows the compiler to usually produce faster and better optimized machine code.
It is perfectly valid to have an implementation of a function in a header file. The only issue with this is breaking the one-definition-rule. That is, if you include the header from multiple other files, you will get a compiler error.
However, there is one exception. If you declare a function to be inline, it is exempt from the one-definition-rule. This is what is happening here, since member functions defined inside a class definition are implicitly inline.
Inline itself is a hint to the compiler that a function may be a good candidate for inlining. That is, expanding any call to it into the definition of the function, rather than a simple function call. This is an optimization which trades the size of the generated file for faster code. In modern compilers, providing this inlining hint for a function is mostly ignored, except for the effects it has on the one-definition-rule. Also, a compiler is always free to inline any function it sees fit, even if it has not been declared inline (explicitly or implicitly).
In your example, the use of const after the argument list signals that the member function does not modify the object on which it is called. In practice, this means that the object pointed to by this, and by extension all class members, will be considered const. That is, trying to modify them will generate a compile-time error.
It is implicitly declared inline by virtue of being a member function defined within the class declaration. This does not mean the compiler has to inline it, but it means you won't break the one definition rule. It is completely unrelated to const*. It is also unrelated to the length and complexity of the function.
If it were a non-member function, then you would have to explicitly declare it as inline:
inline void foo() { std::cout << "foo!\n"; }
* See here for more on const at the end of a member function.
Even in plain C, it is possible to put code in a header file. If you do it, you usually need to declare it static or else multiple .c files including the same header will cause a "multiply defined function" error.
The preprocessor textually includes an include file, so the code in an include file becomes part of the source file (at least from the compiler's point of view).
The designers of C++ wanted to enable object-oriented programming with good data hiding, so they expected to see lots of getter and setter functions. They didn't want an unreasonable performance penalty. So, they designed C++ so that the getters and setters could not only be declared in the header but actually implemented, so they would inline. That function you showed is a getter, and when that C++ code is compiled, there won't be any function call; code to fetch out that value will just be compiled in place.
It is possible to make a computer language that doesn't have the header file/source file distinction, but just has actual "modules" that the compiler understands. (C++ didn't do that; they just built on top of the successful C model of source files and textually included header files.) If source files are modules, it would be possible for a compiler to pull code out of the module and then inline that code. But the way C++ did it is simpler to implement.
As far as I know, there are two kinds of methods, which can be safely implemented inside the header file.
Inline methods - their implementation is copied to places, where they are used, so there is no problem with double-definition linker errors;
Template methods - they are actually compiled at the moment of template instantiation (eg. when someone inputs a type in place of template), so again there is no possibility of double-definition problem.
I believe, your example fits the first case.
C++ standard quotes
The C++17 N4659 standard draft 10.1.6
"The inline specifier" says that methods are implicitly inline:
4 A function defined within a class definition is an inline function.
and then further down we see that inline methods not only can, but must be defined on all translation units:
6 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 (6.2).
This is also explicitly mentioned in a note at 12.2.1 "Member functions":
1 A member function may be defined (11.4) in its class definition, in which case it is an inline member function (10.1.6) [...]
3 [ Note: There can be at most one definition of a non-inline member function in a program. There may be
more than one inline member function definition in a program. See 6.2 and 10.1.6. — end note ]
GCC 8.3 implementation
main.cpp
struct MyClass {
void myMethod() {}
};
int main() {
MyClass().myMethod();
}
Compile and view symbols:
g++ -c main.cpp
nm -C main.o
output:
U _GLOBAL_OFFSET_TABLE_
0000000000000000 W MyClass::myMethod()
U __stack_chk_fail
0000000000000000 T main
then we see from man nm that the MyClass::myMethod symbol is marked as weak on the ELF object files, which implies that it can appear on multiple object files:
"W"
"w" The symbol is a weak symbol that has not been specifically tagged as a weak object symbol. When a weak defined symbol is linked with a normal defined symbol, the normal defined symbol is used with no error. When a weak undefined symbol is linked
and the symbol is not defined, the value of the symbol is determined in a system-specific manner without error. On some systems, uppercase indicates that a default value has been specified.
Keeping the implementation in the class header file works, as I'm sure you know if you compiled your code. The const keyword ensures you don't change any members, it keeps the instance immutable for the duration of the method call.