inline functions link error C++ - c++

Consider the following code:
In header.h
#pragma once
class someClass
{
public:
void foo();
};
In header.cpp
#include "header.h"
inline void someClass::foo(){}
In main.cpp
#include <iostream>
#include "header.h"
using namespace std;
int main()
{
someClass obj;
obj.foo();
}
Here I get a link error because foo function is defined as inline in header.cpp, if I remove the 'inline' keyword, the compile and run will proceed without errors.
Please tell me why I get link error on this 'inline' function?

The way you wrote it, inline applies to the current file scope. When an inline function is in a header, that header is included in a cpp file, and then the function is inlined where it is used in that file's scope, so there is no problem. In this case, your function is available as inline only where it is defined, and no other cpp file sees it, except as a regular member declaration in its class, hence the link error.
If you want it to be inline, add the code and the inline keyword in the header.

Related

using extern keyword for user defined types in c++

I want to use extern keyword for user defined types. This means I've declared object in one file and defined it in other file. I've read that extern keyword is used to declare the variable without defining it. extern keyword is useful when program is split into multiple source files and global variable needs to be used by each of them. Please correct me If I am wrong somewhere.
Here is the programs I've written but unfortunately I am doing something wrong or missing something so I am getting compiler errors.
Prog1.cpp
#include <iostream>
using std::cout;
class test
{
public:
void fun();
};
void test::fun()
{
cout<<"fun() in test\n";
}
test t;
Prog2.cpp
#include <iostream>
using std::cout;
extern test t;
int main()
{
t.fun();
}
Now when I compile these 2 using
g++ -o prog1.cpp prog2.cpp
compiler gives me following errors in prog2.cpp
error: 'test' does not name a type
error: 't' was not declared in this scope
Please help me to know what I've done wrong here.
extern tells the compiler that the definition of t is somewhere else, but the compiler still needs the defintiion of test, as you're using t.fun() to compile Prog2.cpp.
So the solution is, write test.h where you define the class, and then define test t in Prog2.cpp as usual. Include test.h in your Prog2.cpp so that it may know the definition of test. Then build it.
test.h:
#include <iostream>
using std::cout;
class test //definition of test
{
public:
void fun()
{
cout<<"fun() in test\n";
}
};
Prog1.cpp:
#include "test.h"
test t; //definition of t
Prog2.cpp:
#include <iostream>
#include "test.h"
using std::cout;
extern test t; //the definition of t is somewhere else (in some .o)
//and the definition of test is in test.h
int main()
{
t.fun();
}
Now your code should compile and link.
Note that the definition of t is needed by the linker at link-time, so it will search for it in other .o files, but the definition of test is needed by the compiler, at compile-time.
Now it should be obvious that you can put the extern test t; in the header itself so that you dont have to write it in every .cpp file where you want to use the object defined in Prog1.cpp file (which is turned into Prog1.o by the compiler).
Put the extern keyword in the header, not the cpp file. It is the job of the header to tell the compiler there is an externally defined object somewhere.
For example:
program.h (mostly declarations)
struct UserDefinedType
{
void do_stuff();
};
// declare your global object in the header
// so that the compiler knows its name when
// compiling sources that can not otherwise see
// the object
extern UserDefinedType global_udt;
program.cpp (mostly definitions)
#include "program.h"
// define the member functions here
void UserDefinedType::do_stuff()
{
}
// define the global object here
UserDefinedType global_udt;
main.cpp (use the definitions that have been declared in the header)
#include "program.h" // tells the compiler about global_udt
int main()
{
// call the global object that is defined
// in a different source file (program.cpp)
global_udt.do_stuff();
}
NOTE: If we didn't declare the object global_udt in the header file then main.cpp would not know of its existence and the compiler would complain if we tried to use it.
So the header needs to only declare the object and not define it hence the extern keyword is needed.
Please note that a variable declared outside the class scope is a variable with external linkage(if not explicitly used the static keyword) or with internal linkage(if the static keyword is put in the left of the variable type), extern is necessary if you want to use it in multiple files.
Suppose this file is called MyVariable.h
int myNumber = 0; // Initialization of the variable myNumber, external linkage
static int myStaticNumber; // Initialization of the variable myStaticNumber, internal linkage(only the file in which it's declared)
And this file is OtherFile.cpp
extern int myNumber; // Not a initialization because it's already initialized in another file, works fine
extern int myStaticNumber; // ERROR, this variable has internal linkage!!
You may wonder why myStaticNumber was initialized and not just declared, that occurs because static variables are initialized to their default values by default.

C++ I have a function used in all my headers

I have a function that is the same across all my header files and main.cpp if I define it in main.cpp will they all be able to use it once they are included or will they have a compiler issue?
Still new to this whole header file business. Thanks in advance.
In the header file (myfunction.h), you need to have only declaration of the function:
int foo(int param);
In the main.cpp (or any other cpp file - better choice would be myfunction.cpp - just make sure definition is included in exactly one file!) file, you need to have definition of the function:
int foo(int param)
{
return 1;
}
In all other source (cpp) files where you're using function foo, just include myfunction.h and use function:
#include "myfunction.h"
void someotherfunction()
{
std::cout << foo(1) << std::endl;
}
Compiler only needs to see declaration of the function before it is used. Linker will connect definition of the function with the places you've used the function. If you forget to write definition in main.cpp file, you will not get compiler, but a linker error. It may be worth of mentioning that compiler is compiling each cpp file separately, and linker's job is to combine all compiler object files and to produce final output file. On most setups, linker will be called automatically after compiling, so you may not be familiar with it.
If you include entire function definition in the header file, that definition will be compiled in each translation unit where header file is included, and you will get multiple symbol definition linker error, or something similar - that's why you need to include only declaration of the function inside header file. However, there are exceptions for this - for example, you may declare your function inline - other answers explain this approach.
So, now myfunction.h contains the function declaration:
#ifndef MY_FUNCTION_H
#define MY_FUNCITON_H
// declaration
int myfunction();
#end if
myfunction.cpp contains the function definition:
int myfunction()
{
return 4;
}
Now, in file1.cpp and in file2.cpp you want to use this function, so you're including myfunction.h:
// file1.cpp
#include "myfunction.h"
// somewhere in the file
void foo()
{
std::cout << myfunction();
}
... and in the second file:
// file2.cpp
#include "myfunction.h"
// somewhere in the file
void bar()
{
/// ...
std::cout << myfunction();
}
Header files in C and C++ are a language artifact. They are the consequence of the fact, that C and C++ can be implemented as a single-pass compiler. In contrast, Pascal - for example - has a two-pass compiler, that skips over unknown entities during the first pass, and fills in the missing bits in a second pass. Consequently, in C and C++ every type, object, and method must be declared before it can be used. This is the main responsibility of header files.
Header files are expanded into any file that includes them. In other words: The preprocessor replaces the statement #include "foo.h" with the contents of the file "foo.h". With this being the case you need to be careful to not violate the single definition rule: An entity must not be defined more than once.
To meet both requirements you have two options: Declare and define the function in the header, using the inline keyword, or declaring it in the header only, and defining it in another compilation unit.
The following code illustrates both solutions:
// foo.h
inline void foo() {
// Method is implemented in this header file.
// It is marked 'inline' to prevent linker errors
// concerning multiply defined symbols.
...
}
Delaration in header only, implementation in another compilation unit:
// foo.h
extern void foo();
// foo.cpp (or another compilation unit)
void foo() {
...
}
Regardless of which solution you go with, you can use foo() from any compilation unit. If you want to use it from "main.cpp" the code would look something like this:
// main.cpp
#include "foo.h"
int main() {
foo();
}
So you have a function which is used in all your header files, why don't you make a utility.h which keeps track of these types of functions and inline the functions in the .h ?
Declare the function prototype in a custom header file:
int add(int a, int b);
let say header file name is myfunction.h and include it wherever you need the function.
now you can define a function on another.cpp or main.cpp
int add(int a, int b){
return a+b;
}
include your custom header file like this:
#include "myfunction.h"
remember your main.cpp and other cpp files and the new header file should be in the same path.
If you have two files:
main.cpp
#include "func.h"
int main(){
hello();
std::cout<<" world!\n";
return 0;
}
& func.h
#ifndef FUNC_H
#define FUNC_H
#include <iostream>
void hello(void){
std::cout<<"hello";
}
#endif
iostreams objects and functions e.t.c will work fine from within main.cpp.
This posts answers sum up #ifndef pretty well if you would like to know more.

How to call a c++ function without including the header file and duplication?

I am doing C++ coding.
From file f2.cpp, I need to call a function f1() defined in f1.cpp but not deleared in f1.h.
I cannot do it by including the f1.h in f2.cpp.
I do not want to define another function that does the same thing, it is duplication.
How to solve this problem ?
Thanks
UPDATED
After reading the solutions, I am going to add the declearation of f1() in f1.h.
in f1.h, it has
namespace name1{
namespace name2{
class class1{};
class class2{};
}
}
f1() is just an utility function that does not touch members of clas1 and class2.
Currently, f1() is defined within a namespace (without a name) in f1.cpp.
namespace{
f1(){
}
}
But, in f1.h, it has a namespace defination name1 and name2.
Where should I put f1() declearation in f1.h ?
Now, I put f1() in name1::name2 in f1.h and included f1.h in f2.cpp, i got link error:
undefiend name1::name2::f1() from f2().
UPDATED
If I put delaration of f1() in f1.h outside any namespace and also include f1.h from f2.cpp, i got link error: undefined symbol of f1() in f2(), why ?
Any help will be appreciated !
Declare the function as extern in f2.cpp
//f2.cpp
extern void f(); //function declared but defined elsewhere
int main() {
f();
}
//f1.cpp
void f() {
//function declaration
}
g++ f2.cpp f1.cpp , would work fine.
Having said that, you could also do a #include of f2.cpp, which would work but is definitely a bad idea, because if you compile both files together you will multiple definition error. If in your control the right thing would be to have a f1.h with the function declaration.
UPDATE: For your modified question using namespaces, by using unnamed-namespace around f() you are explicitly telling the compiler to restrict the visibility of the function to just that file. You could change to a named namespace and then refer to its declaration in header file
The utility function you want to use is in an anonymous namespace, which is similar in concept to a static. It makes the function only visible to that source file.
If you do not want to move the function out of f1.cpp, then you need to make the interface to the utility function public in some way. One way is to move the function into a new namespace that has a name, something like f1_util perhaps. Then you can declare the presence of the utility function in f1.h.
// f1.cpp
namespace {
// move f1() out of this
}
namespace f1_util {
void f1(){
//...
}
}
using namespace f1_util;
//... rest of f1.cpp
// f1.h
namespace f1_util {
void f1();
}
//... rest of f1.h
Better may be to move the utility function into a new source file, say, util.cpp, and make sure it is not in an anonymous namespace. Then define a util.h that declares it. Then have both f1.cpp and f2.cpp include the util.h.
Put the declaration of f1() in f2.cpp. The location of a declaration doesn't matter to the compiler, it's just a programming convention that declarations and definitions get put in corresponding header and source files. It's a good practice to follow, though: if you change the header of a function in f1.cpp, you only have to update that declaration in f1.h, you don't have to look for it in all the other .cpp files that call the function. This is the reason we use header files in the first place, for modularity.
Why don't you just include f1.cpp or declare the function in f1.h?

C++ Templates Declaration Order

I am trying to compile a minimal example which instantiates
a template class. The example compiles fine when a certain order
of declarations is kept, but fails otherwise.
temp.h:
#include <iostream>
template <bool display>
class test {
public:
void sayHi();
};
temp.cpp:
#include "temp.h"
template <bool display>
void test<display>::sayHi () {
if (display) std::cout << "Hi";
}
main.cpp:
#include <iostream>
#include "temp.h"
int main () {
test<true> myobject;
myobject.sayHi();
return 0;
}
This is the standard of how to include classes.
In GCC 4.4.6, this fails with the error
main.cpp:(.text+0x3a): undefined reference to `test::sayHi()'
However, the example compiles when I do a #include "temp.cpp" instead of #include "temp.h" in main.cpp
file, so that the compiler reads the class declaration in temp.h first, then
sees the content of temp.cpp and only afterwards the content of main.cpp.
When I use non-template classes, it works fine to include just .h files
in main.cpp -- what is going wrong here? Note that the temp.cpp is included
in my Makefile, so it definitely should not be forgotten by the compiler.
Thanks for any help.
See the C++ FAQ Lite entry [35.12] Why can't I separate the definition of my templates class from its declaration and put it inside a .cpp file?.
The definition (aka body) of the sayHi() method must be in the temp.h header, or in another included file; the full code is needed when you instantiate test<true>.
With templates, both declaration and definition must be in the same file. You can do this by either putting all your code in one file (and making the function definitions inline or not, it's up to you), or making the declaration and definitions seperate, but including the definitions file at the bottom of the .h file.
So it would be
tmp.h:
#include <iostream>
template <bool display>
class test {
public:
void sayHi();
};
#include "tmp.cpp"
and tmp.cpp and main.cpp remain the same (but you don't give tmp.cpp to the compiler to compile since it's included by tmp.h).
Many people name the files that have template function definitions in them with a .template extension instead of .cpp extension (it lets you know it's not to be compiled, plus it looks less weird than including a .cpp file), but you don't have to.

Inlined constructors? Explain this behavior[C++]

Consider this code
#include <iostream>
#include <cstdio>
using namespace std;
class Dummy {
public:
Dummy();
};
inline Dummy::Dummy() {
printf("Wow! :Dummy rocks\n");
}
int main() {
Dummy d;
}
All is good here!
Now I do this modification. I move the declaration of Dummy to "dummy.h".
class Dummy {
public:
Dummy();
};
And define the constructor Dummy() as following in "dummy.cpp"
#include "dummy.h"
inline Dummy::Dummy() {
printf("Wow! :Dummy rocks\n");
}
And finally, I have my main file as:
#include <iostream>
#include <cstdio>
#include "dummy.h"
using namespace std;
int main() {
Dummy d;
}
It compiles fine, but I get a linker error complaining an undefined reference to Dummy::Dummy().
Any insights.
--
You have to put all inline functions (including methods and constructors/destructors) in a header file, where they are declared.
Though this code should work either way, with main() calling the constructor as if the inline keyword was not there. Are you sure you are passing object files from both compilation units to the linker?
You should think how compiling works at C++ and the idea of separate compiling units used at C++ and encapsulation gained using headers and cpp files.
Look here:
http://www.parashift.com/c++-faq-lite/inline-functions.html#faq-9.6
The inline tells the complier that instead of calling the function to "copy - paste" its code at the place of the function call. When you put the inline definition in a CPP file it won't be visible during linking to other compiled units (its in cpp file not in h file) so the compiler understand from the signature placed at the class that there is no-paramter Con's so it won't implement the default one. But the linker can't find the function body cause it is implemnted inline at the cpp file.
Try removing the inline specifier from the your implementation file. If my understanding is correct, you can only inline in a header