Is it not necessary to define a class member function? - c++

The following code compiles and runs perfectly,
#include <iostream>
class sam {
public:
void func1();
int func2();
};
int main() {
sam s;
}
Should it not produce a error for the lack of class member definition?

If you don't call the member functions, they don't have to be defined. Even if you call them, the compiler won't complain since they could be defined in some other compilation unit. Only the linker will complain. Not defining functions is accepted and common to force an error for undesired behavior (e.g. for preventing copying).

Yes it is perfectly valid to not define a class member function if it is not used. That is also true for non-member functions. A definition is required for virtual functions, though. But pure virtuals can omit definitions if they aren't used.
"Used", btw, does not include refering to the function within sizeof. In other words, this is still valid:
sizeof (s.func2()); // still not used!

You can define it elsewhere (like another file)
void Sam::func1()
{
// do stuff here
}

From MSDN Linker Error LNK2019

You did define declared it. You just didn't add implementation provided a function prototype. The linker may display a warning if you do not have a function definition (for instance, Borland C++ Builder 5 does not).

Related

Undefined reference to inlining function with const reference parameters from test case [duplicate]

NB This is not a question about how to use inline functions or how they work, more why they are done the way they are.
The declaration of a class member function does not need to define a function as inline, it is only the actual implementation of the function. For example, in the header file:
struct foo{
void bar(); // no need to define this as inline
}
So why does the inline implementation of a classes function have to be in the header file? Why can't I put the inline function the .cpp file? If I were to try to put the inline definition in the .cpp file I would get an error along the lines of:
error LNK2019: unresolved external symbol
"public: void __thiscall foo::bar(void)"
(?bar#foo##QAEXXZ) referenced in function _main
1>C:\Users\Me\Documents\Visual Studio 2012\Projects\inline\Debug\inline.exe
: fatal error LNK1120: 1 unresolved externals
The definition of an inline function doesn't have to be in a header file but, because of the one definition rule (ODR) for inline functions, an identical definition for the function must exist in every translation unit that uses it.
The easiest way to achieve this is by putting the definition in a header file.
If you want to put the definition of a function in a single source file then you shouldn't declare it inline. A function not declared inline does not mean that the compiler cannot inline the function.
Whether you should declare a function inline or not is usually a choice that you should make based on which version of the one definition rules it makes most sense for you to follow; adding inline and then being restricted by the subsequent constraints makes little sense.
There are two ways to look at it:
Inline functions are defined in the header because, in order to inline a function call, the compiler must be able to see the function body. For a naive compiler to do that, the function body must be in the same translation unit as the call. (A modern compiler can optimize across translation units, and so a function call may be inlined even though the function definition is in a separate translation unit, but these optimizations are expensive, aren't always enabled, and weren't always supported by the compiler)
functions defined in the header must be marked inline because otherwise, every translation unit which includes the header will contain a definition of the function, and the linker will complain about multiple definitions (a violation of the One Definition Rule). The inline keyword suppresses this, allowing multiple translation units to contain (identical) definitions.
The two explanations really boil down to the fact that the inline keyword doesn't exactly do what you'd expect.
A C++ compiler is free to apply the inlining optimization (replace a function call with the body of the called function, saving the call overhead) any time it likes, as long as it doesn't alter the observable behavior of the program.
The inline keyword makes it easier for the compiler to apply this optimization, by allowing the function definition to be visible in multiple translation units, but using the keyword doesn't mean the compiler has to inline the function, and not using the keyword doesn't forbid the compiler from inlining the function.
This is a limit of the C++ compiler. If you put the function in the header, all the cpp files where it can be inlined can see the "source" of your function and the inlining can be done by the compiler. Otherwhise the inlining would have to be done by the linker (each cpp file is compiled in an obj file separately). The problem is that it would be much more difficult to do it in the linker. A similar problem exists with "template" classes/functions. They need to be instantiated by the compiler, because the linker would have problem instantiating (creating a specialized version of) them. Some newer compiler/linker can do a "two pass" compilation/linking where the compiler does a first pass, then the linker does its work and call the compiler to resolve unresolved things (inline/templates...)
The c++ inline keyword is misleading, it doesn't mean "inline this function". If a function is defined as inline, it simply means that it can be defined multiple times as long as all definitions are equal. It's perfectly legal for a function marked inline to be a real function that is called instead of getting code inlined at the point where it's called.
Defining a function in a header file is needed for templates, since e.g. a templated class isn't really a class, it's a template for a class which you can make multiple variations of. In order for the compiler to be able to e.g. make a Foo<int>::bar() function when you use the Foo template to create a Foo class, the actual definition of Foo<T>::bar() must be visible.
The reason is that the compiler has to actually see the definition in order to be able to drop it in in place of the call.
Remember that C and C++ use a very simplistic compilation model, where the compiler always only sees one translation unit at a time. (This fails for export, which is the main reason only one vendor actually implemented it.)
I know this is an old thread but thought I should mention that the extern keyword. I've recently ran into this issue and solved as follows
Helper.h
namespace DX
{
extern inline void ThrowIfFailed(HRESULT hr);
}
Helper.cpp
namespace DX
{
inline void ThrowIfFailed(HRESULT hr)
{
if (FAILED(hr))
{
std::stringstream ss;
ss << "#" << hr;
throw std::exception(ss.str().c_str());
}
}
}
Because the compiler needs to see them in order to inline them. And headers files are the "components" which are commonly included in other translation units.
#include "file.h"
// Ok, now me (the compiler) can see the definition of that inline function.
// So I'm able to replace calls for the actual implementation.
Inline Functions
In C++ a macro is nothing but inline function. SO now macros are under control of compiler.
Important : If we define a function inside class it will become Inline automatically
Code of Inline function is replaced at the place it is called, so it reduce the overhead of calling function.
In some cases Inlining of function can not work, Such as
If static variable used inside inline function.
If function is complicated.
If recursive call of function
If address of function taken implicitely or explicitely
Function defined outside class as below may become inline
inline int AddTwoVar(int x,int y); //This may not become inline
inline int AddTwoVar(int x,int y) { return x + y; } // This becomes inline
Function defined inside class also become inline
// Inline SpeedMeter functions
class SpeedMeter
{
int speed;
public:
int getSpeed() const { return speed; }
void setSpeed(int varSpeed) { speed = varSpeed; }
};
int main()
{
SpeedMeter objSM;
objSM.setSpeed(80);
int speedValue = A.getSpeed();
}
Here both getSpeed and setSpeed functions will become inline

Does C++ accept inline virtual function while performing polymorphism?

//header.h
#include<iostream>
using namespace std;
struct Base {
virtual void vf();
};
struct Derived :Base {
virtual void vf();
};
inline void Base::vf() {
cout << "Base::vf()" << endl;
}
inline void Derived::vf() {
cout << "Derived::vf()" << endl;
}
//source.cpp
#include"header.h"
int main() {
Base *pb = new Derived;
pb->vf();
}
//source2.cpp
#include"header.h"
It compiles and works in MSVC and g++.
But if I remove both inline keywords, a duplicate definition error will be caught by the linker since I include function definition twice, which will break the ODR.
Since I call the virtual function with a base pointer, it should be decided at run-time, and the compiler will ignore my inlining request, causing the duplicate error.
Do I get something wrong?
As the code is currently written, the member functions are defined in header.h and marked inline. That's okay from the perspective of the language definition: inline means "it's okay to have multiple [identical] definitions of this function". From a maintenance perspective it can make things harder. In particular, when you do this, every time you change the implementation of any of those functions you have to recompile all of the source files that use that header. Putting the definitions of those functions into their own source file[s] means you only have to recompile the file[s] that changed.
If you don't want to mark your functions inline (and you don't want to define them inside the class definition, which makes them implicitly inline), then you have to put each function definition into exactly one source file. A useful first step is to define all of the non-inline member functions of a class in a single source file. So your source2.cpp might look like this (yes, that's member functions from two classes):
#include "header.h"
#include <iostream>
void Base::vf() {
std::cout << "Base::vf()\n";
}
void Derived::vf() {
std::cout << "Derived::vf()\n";
}
and you'd remove those definitions from header.h. So now header.h contains only the class definition; source2.cpp has the definitions of the member functions; and source.cpp has the main function.
The One Definition Rule is mandatory. It is required by C++. A given object or a function must be defined exactly once. Removing the inline keyword (in your case) violates this rule, making the resulting program ill-formed.
Runtime polymorphism and virtual function dispatch happens at run time. You can only get to the run time part if your program is well-formed. If it breaks the ODR it is not well-formed, so how runtime polymorphism and virtual function dispatch works becomes a moot point. If your program is ill-formed there won't be anything to run and no base pointer at all.
It is true that an ODR violation does not require a diagnostic, but the resulting code is still broken. Please write a thank-you note to your compiler for alerting you to the problem.

if I define a function in the implementation (.cpp) file without defining it in the header file what happens?

I'm a C++ noob. I have a foo.cpp file which defines a function,
void sort() {
// details of sort algorithm
}
I have not defined this in the corresponding header file, but I get no compilation error. I noticed this is taken as a static method. Is that the case? What exactly have I done here?
EDIT:
I've noticed that inside this method I can't use this, (ex: this->bar), hence my assumption that this is a static function. This actually happened when I wanted a 'private' method, but forgot to declare it in the header file. Is there an actual use of such a function?
It is not invisible outside of that compilation unit, it is not bound to a single compilation unit, it is just a definition that needs a declaration in order to be called. Like any other definition.
wtf.cpp:
#include <iostream>
void f(){ std::cout<< "f();"; }
omg.cpp:
void f(); // I can declare wherever I use it.
int main(){ f(); }
$ g++ wtf.cpp omg.cpp && ./a.out
Output: f();
No, it is not taken as a static function. It is just not visible to the other transllation unnits, and so you cannot use it.
The difference in regard to a static method is, that the linker sees the function. So if you define a function with the same name in another translation unit, you will probably either get a linker error (best case) or the wrong method called at times.
PS: I talk about a functions rather than methods here, because in C++ a method typically is part of a class, and you cannot define a method for a class if that method isn't declared in that class' declaration.
the function is like the others said available in that translation unit.
But you can still access it from anywhere as it will just have external linkage. so just do this:
void foo()
{
extern void sort();
sort();
}
Nothing happens. The function will be there and essentially available, but without a prototype/forward declaration other translation units/parts of the code won't know it's actually there (and based on optimization level it might be excluded from the resulting executable code).
You've created a function that is only visible to that compilation unit (and others that include the source itself).
You've just have defined a free function .
You can use in your implementation file given that the declaration is above the calls (the parser "reads" the source file from top to bottom) :
void fun(){
mysort(); // Compile Error
void mysort(){}
void anotherFun(){
mysort(); // Works here
}
To get rid of this boundary effect, you can add a prototype of the function at the beginning of the file. I often use this "free function" for small conversion macros.
Example :
char* BigEndianToLitteEndian( char word[], int size); // prototype
void routine()
{
....
le = BigEndianToLittleEndian( be, SIZE );
....
}
char* BigEndianToLitteEndian( char word[], int size){ // implementation
....
}
Even though it's only in the implementation file, it's not static unless you specify static.
Static functions, in addition to restricting access, may also allow for compiler optimizations for better performance.
See static function in C, notably #Stephen_Canon's answer.
And also it might be very bad if the same function defined inside some other cpp file with the same signature.

C++: Do function wrappers work with inline?

If you've enabled full optimizations in your compiler and have classes setup like this:
class A
{
void Do_A_Stuff();
};
class B
{
A a;
void Do_B_Stuff() { a.Do_A_Stuff(); }
};
class C
{
B b;
void Do_C_Stuff() { b.Do_B_Stuff(); }
};
class D
{
C c;
void Do_D_Stuff() { c.Do_C_Stuff(); }
};
Is there ever a situation where calling Do_D_Stuff() would be slower than directly calling Do_A_Stuff()? Also, would this require the inline keyword on each wrapper 'chain' or, since it is only a suggestion, could the compiler decide to optimize this without the keyword?
I realize there is a lot of information about inlining available, but I could not find any information specifically about chaining many wrappers together.
Also, would this require the inline keyword on each wrapper 'chain' or, since it is only a suggestion, could the compiler decide to optimize this without the keyword?
Yes, the compiler could decide to optimize it anyway, and it could also decide not to optimize it even if you specified the inline keyword (possibly producing a warning if the appropriate compiler options are set) - notice, that member functions defined in a class definition are implicitly marked as inline.
In general, if inlining is possible, the compiler will decide whether to inline or not based on the body of the function being called. However, inlining may not be possible at all if the function is a virtual function, or if the definition of the function is not visible to the compiler.
Provided that the conditions for inlining are satisfied and that the compiler considers it appropriate, there is no technical problem in inlining over a chain of function calls.
As a minor remark, notice that the functions in your classes should be public, otherwise they won't be accessible to your wrappers.
The functions are defined inside the class definition, so the inline keyword is implicit in this case.

Local classes inside inline non-member function produces LNK2005 with MSVC2005

Apparently, MSVC2005 fails to inline local classes' member functions which leads to LNK2005.
I'm facing this LNK2005 error when compiling the following:
common.h content:
inline void wait_what()
{
struct wtf
{
void ffffuuu() {}
} local;
}
foo.cpp content:
#include "common.h"
void foo()
{
wait_what();
}
bar.cpp content:
#include "common.h"
void bar()
{
wait_what();
}
LNK2005.cpp content:
// forward declarations
void foo();
void bar();
int main()
{
foo();
bar();
return 0;
}
The error message is:
error LNK2005: "public void __thiscall `void__cdecl wait_what(void)'::`2'::wtf::ffffuuu(void)" (?ffffuuu#wtf?1??wait_what##YAXXZ#QAEXXZ) already defined in bar.obj
About local classes, ISO IEC 14882-2003 says:
9.8 Local class declarations
A class can be defined within a function definition; such a class is called a local class. The name of a local class is local to its enclosing scope. The local class is in the scope of the enclosing scope, and has the same access to names outside the function as does the enclosing function. Declarations in a local class can use only type names, static variables, extern variables and functions, and enumerators from the enclosing scope.
An enclosing function has no special access to members of the local class; it obeys the usual access rules (clause 11). Member functions of a local class shall be defined within their class definition, if they are defined at all.
Did I miss something?
To me, it looks like it is a compiler bug. GCC and MSVC2008 compile it just fine. However, I wonder whether they would really inline the call or just discard one of the two symbols during the link phase. As an interesting note, you can notice that there is even no call to this local class member function.
I wonder whether there is a workaround for MSVC2005. I tried to search MSDN for this typical problem without much success: I wasn't even capable of finding a list of known bugs for the compiler.
Attachment: LNK2005.zip
it was a bug in visual studio 2005, it was fixed in vs 2008
It looks like a bug to me. Maybe that's why it works in VS2008. (Incidentally, Microsoft, this is a good reason for breaking the IDE/compiler dependency in Visual Studio.)
As for a workaround, try explicitly adding inline, or not inlining wait_what.