I have hpp file with declaration:
namespace X {
class Y {
public:
[other functions]
inline float basicFunction();
int someFunction();
[other functions]
};
}
And in cpp file:
namespace X {
[implementations etc.]
inline float Y::basicFunction() {
return someValue * someMath / moreMath;
}
int Y::someFunction() {
return basicFunction() * 100;
}
[other functions]
}
I'm using it at other cpp file, but I think this isn't problem. Compiling with:
g++ -c someclass.cpp -o someclass.o -std=c++11
g++ -c main.cpp -o main.o -std=c++11
g++ main.o someclass.o -o main -std=c++11 -O0
Throw error:
main.o: In function `main':
main.cpp:(.text+0x4d9): undefined reference to `X::Y::someFunction()'
Why? How I can compile it correct?
I know that someFunction() is useless, but this is called many times and I just like that way.
All code above isn't real, so may have bugs, but on my program it's (I think) correct
I tried many combinations (both functions with same return type, both inline, none inline etc.) and no effect.
Solved. Function cannot be inline.
Still don't know why it worked after some attempts after deleted inline but nevermind.
Explanation why function in this code can't be inline is simple. Compiler, when see "inline", don't create pointer to function, but paste code in the place of reference.
Just my mistake...
Related
The following is a simple example for separate compilation:
// mod.cpp
#include <cstdio>
class MyModule {
public:
void print_msg();
};
void MyModule::print_msg() {
printf("hello from module\n");
}
// main.cpp
class MyModule {
public:
void print_msg();
};
int main() {
MyModule a;
a.print_msg();
}
We can compile and run it with
g++ main.cpp -c -o main.o
g++ mod.cpp -c -o mod.o
g++ main.o mod.o -o main
./main
The above works fine, but if I move the definition of MyModule::print_msg inside the class:
// mod.cpp
#include <cstdio>
class MyModule {
public:
void print_msg() { printf("hello from module\n"); }
};
I get an 'undefined reference' error for compiling main:
g++ main.cpp -c -o main.o # OK
g++ mod.cpp -c -o mod.o # OK
g++ main.o mod.o -o main # undefined reference error
/usr/bin/ld: main.o: in function `main':
main.cpp:(.text+0x23): undefined reference to `MyModule::print_msg()'
collect2: error: ld returned 1 exit status
I know that the former is the standard way and the class definition should go to a header file, but I wonder why the second method doesn't work.
Functions defined inside the class are implicitly inline. C++ requires:
The definition of an inline function [or variable (since C++17)] must be reachable in the translation unit where it is accessed.
Since you only defined it in mod.cpp, no definition is reachable in main.cpp, and compilation fails.
Typically, you'd put the definition of the class, and the definition of all functions defined within it, in a header file to be included by all users of the class. The functions defined outside the class then go in a .cpp file. That way a single consistent definition of all the inline functions is available to all users of the class, and you're not repeating the definition of the class in each .cpp file manually.
hope you guys are doing well. I am just getting linker error in C++ , I don't know why? Everything is correct....
Check below testing.h file
#ifndef __MYClass__
#define __MYClass__
#include<iostream>
using namespace std;
class Abc {
private:
int a;
public:
void input();
void display();
};
#endif
and here's implementation of these functions in Functions.cpp file.
#include"testing.h"
void Abc::input() {
cout<<"Enter any value : ";
cin>>a;
}
void Abc::display() {
cout<<"You Entered : "<<a;
}
And now, in main.cpp
#include<iostream>
#include"testing.h"
using namespace std;
int main() {
Abc obj;
obj.input();
obj.display();
return 0;
}
All files are compiled successfully.
In main.cpp Linker says....
g++ -Wall -o "main" "main.cpp" (in directory: /home/Welcome/C++ Practices/testingLinux)
/usr/bin/ld: /tmp/ccYI9LAy.o: in function main': main.cpp:(.text+0x10): undefined reference to Abc::input()'
/usr/bin/ld: main.cpp:(.text+0x1c): undefined reference to `Abc::display()'
collect2: error: ld returned 1 exit status
Compilation failed.
I'm using built-in linux compiler...
There are multiple ways you can fix this but before that please read up on Translation Unit.
Coming to your problem.
When you write
g++ -Wall -o main main.cpp
The compiler will pick up main.cpp for compilation and expand testing.h that includes the declaration for class ABC and with this header file it can determine what is the size of ABC and be able to generate instructions reserving space for obj on the stack. It can't see the definition for input() and display() hence defers that task to the linker. Note that testing.cpp is not in the picture at all since the compiler doesn't know that the implementation of ABC is in testing.cpp. Now when the linker tries to resolve the symbols input() it fails to find the definition for it and throws the error
undefined reference to Abc::input()
So, to fix this you can tell explicitly upfront that it also needs to take in testing.cpp while compiling main.cpp by
g++ -o main main.cpp testing.cpp
Another way is to create a dynamic library out of testing.h and testing.cpp
g++ -shared -fPIC testing.cpp -o libtest
and then link it against main.cpp
g++ -o main main.cpp -I. -L. libtest
What this does is that the compiler still can't figure out the definition of input() and display() but the linker can since now the library containing the definitions is provided to it.
You are not compiling Functions.cpp file.
This should fix your issue:
g++ main.cpp Functions.cpp
I run an up to date debian testing (with kernel 4.19).
Helpers are not found on my system (but they exist in the header, Qt jumps to them)
#include "bpf/bpf.h"
int main (){
int r = bpf_create_map(BPF_MAP_TYPE_ARRAY,1,1,1,0);
return 0;
}
Compilation results in
undefined reference to `bpf_create_map(bpf_map_type, int, int, int, unsigned int)'
compiled with
g++ -c -pipe -g -std=gnu++1z -Wall -W -fPIC -DQT_QML_DEBUG -I. -I../../Qt/5.13.0/gcc_64/mkspecs/linux-g++ -o main.o main.cpp
g++ -lbpf -o server main.o
Same result with
g++ main.cpp -lbpf -o out
I have the libbpf-dev installed as well and i have the associated libraries (a and so).
What is wrong?
Update
even the following code won't work
#include <linux/bpf.h>
int main (){
//int r = bpf_create_map(BPF_MAP_TYPE_ARRAY,1,1,1,0);
bpf_attr attr = {};
attr.map_type = BPF_MAP_TYPE_ARRAY;
attr.key_size = 1;
attr.value_size = 1;
attr.max_entries = 1;
bpf(BPF_MAP_CREATE, &attr, sizeof(attr));
return 0;
}
results in
error: 'bpf' was not declared in this scope
Update2:
BTW, key size is mandated to be 4 and not 1; but it is a point aside, that was unrelated to my problem here.
Namespace issue due to compiling in C++, you probably want:
extern "C" {
#include "bpf/bpf.h"
}
int main()...
Regarding your second error (error: 'bpf' was not declared in this scope), this is not directly related to libbpf, this is because there is no function simply called bpf() to actually perform the syscall. Instead you have to use the syscall number. For example, libbpf defines the following:
static inline int sys_bpf(enum bpf_cmd cmd, union bpf_attr *attr,
unsigned int size)
{
return syscall(__NR_bpf, cmd, attr, size);
}
... and uses sys_bpf() after that, the same way you try to call bpf() in your sample.
For the record, “BPF helpers” often designates BPF functions that you call from within a BPF program, which is not the case here. Hence some confusion in the comments, I believe.
I am trying to link a dll with a very simple testing program, but I am getting an error, that I will describe at the end of the post.
frvt11.h - Interface (just relevant code) I need to implement to create my dll
namespace FRVT {
class Interface {
public:
static std::shared_ptr<Interface>
getImplementation();
}
}
implementation.h - Header of my implementation of Inteface
#include "frvt11.h"
namespace FRVT {
class Implementation : public FRVT::Interface {
public:
static std::shared_ptr<Interface>
getImplementation();
}
}
implementation.cpp - My implementation of Interface
UPDATE: change from Implementation::getImplementation to Interface::getImplementation
#include "implementation.h"
using namespace FRVT;
std::shared_ptr<Interface>
Interface::getImplementation() {
std::cout<<"getImplementation";
return std::make_shared<Implementation>();
}
main.cpp
UPDATE: Explicitly indicate the namespace Interface::
#include "frvt11.h"
using namespace FRVT;
int main(){
auto obj = Interface::getImplementation();
return 0;
}
compilation directives
UPDATE: include of -L/dll-directory where are all .h, .cpp and dll
g++ -std=c++11 -c -Wall -Werror -m64 -fPIC implementation.cpp
g++ -std=c++11 -shared -m64 -o libimplementation.so implementation.cpp
g++ -std=c++11 -Wall -m64 -o main main.cpp -L/dll-directory -limplementation
error
UPDATE: Original problem solved
main.cpp: In function 'int main()':
main.cpp:6:34: error: 'getImplementation' was not declared in this scope
auto obj = getImplementation();
How to solve this error? I was expecting that the linker would do the "magic" to say to main.cpp, that the implementation of referred function would be at the dll. What am I doing wrong?
At implementation.cpp I've changed from:
Implementation::getImplementation()
to:
Interface::getImplementation()
At main.cpp I've explicitly indicate the interface, like bellow:
auto obj = Interface::getImplementation();
And finally I've used the -L directive to indicate where was the the generated dll.
I made a program to test my knowledge on class but I had some troubles.
foo.h:
#include <iostream>
using namespace std;
class foo
{
private:
int a;
public:
foo();
};
foo.cc:
#include <iostream>
#include "foo.h"
using namespace std;
foo::foo()
{
a = 0;
}
And main.cc:
#include<iostream>
#include "foo.h"
int main()
{
foo a;
return 0;
}
I compiled this with g++ main.cc -o main. Then I got
-bash-4.1$ g++ main.cc -o main
/tmp/cc5Hnes8.o: In function `main':
main.cc:(.text+0x10): undefined reference to `foo::foo()'
collect2: ld returned 1 exit status
I think there should be a really stupid mistake here but I really cannot find it. I've been struggling on this whole night...
Appreciate any help!
You are asking the compiler to not only translate main.cc but also perform the final link to produce the executable main. This second step cannot be done because main.cc references the function foo::foo whose definition is in foo.cc and therefore not available to the compiler. You can do this:
g++ main.cc -c -o main.o
g++ foo.cc -c -o foo.o
g++ main.o foo.o -o main
The -c flag makes the compiler perform translation only, so this separately compiles main.cc and foo.cc and then links the objects together to obtain the executable. In this way, the definition of foo::foo will end up inside foo.o and will be available at link time.
Or, you can just provide both .cc files. This basically does the same thing as the three commands above:
g++ main.cc foo.cc -o main
You should compile all source (.cc in your case) files:
g++ main.cc foo.cc -o main
When you realize the constructor of foo in foo.cc, you should compile it.
use g++ main.cc foo.cc -o main.