What's wrong withe following C code! - c++

I tried the following code in C as well as C++ .file1 is a c file .file2 is a c++ file and file3 is a header file for name magling.
file1.c
#include<stdio.h>
#include<stdlib.h>
#include "file3.hpp"
int main(int argc,char **argv)
{
int a[5];
int i;
for(i=0;i<5;i++)
a[i] = i;
printf("%d",a[17]);
return 0;
}
file2.cpp
#include "file3.hpp"
int printtrial(int number)
{
return number;
}
file3.hpp
#ifdef __cplusplus
extern "C"
{
#endif
extern int printtrial(int number);
#ifdef __cplusplus
}
#endif
I compile it using the following commands:
gcc -c file1.c
g++ -c file2.cpp
gcc -o output file1.o file2.o
On this it gives the error:
file2.o:(.eh_frame+0x12): undefined reference to `__gxx_personality_v0'
collect2: ld returned 1 exit status
Can anyone tell me what's going on!

As one of your files is compiled as c++ use g++ for linking phase.
See: What is __gxx_personality_v0 for?

C and C++ executables require the presence of some libraries, which are included during the linking stage:
gcc -o output file1.o file2.o
The problem here is that you are trying to link a C++ file using a C linker. gcc simply fails to locate some libraries required by the C++ runtime. To solve this you must use g++, like yi_H said.

Related

Including files correctly , but still getting linker error

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

Calling C code from C++ with using extern "C"

I have 3 files with me, one c++ file, main.cpp, one c file, test.c and one header file, test.h
I wanted to try and use C code into C++ file. For the same reason, I have declared an function in test.h and defined that in test.c and using that in main.cpp
main_temp.c is just for explanation.
test.h
void test(int);
test.c
#include <stdio.h>
void test(int a) {
printf("%d", a);
main_temp.cpp
#include "test.h"
int main() {
foo(5);
}
Here, I understand why this would not work. C symbol would be simple 'foo' but since C++ does more things while creating symbols, it might be 'void#test(int)' and to solve this name mangling problem, I have to treat C++ symbol as a C symbol. So, I would use extern "C" and my main.cpp becomes as like:
main.cpp
extern "C" {
#include "test.h"
}
int main() {
foo(5);
}
I could not understand as to why this would not work! I get :
main.cpp:(.text+0xa): undefined reference to `test`
Can somebody share the insights?
I trust you compile or link them together? Else that would be the cause. On gcc it would be something like:
g++ -c -o main.o main.cpp
gcc -c -o test.o test.c
g++ -o a.out main.o test.o
Assuming you have no bugs with compiling/linking, compile both main.cpp and test.c into object files and run nm on both. It will show what symbol main.o wants and what symbol test.o exports. It should become clear then why linker cannot do its job.

Calling C++ function from a C file gives an "undefined reference" compiler error [duplicate]

This question already has answers here:
What is an undefined reference/unresolved external symbol error and how do I fix it?
(39 answers)
Closed 7 years ago.
I have the following files - main.c, RULE_MINE.h and RULE_MINE.cpp
main.c
#include "RULE_MINE.h"
int main()
{
checker();
}
RULE_MINE.h
#ifndef HEADER_FILE
#define HEADER_FILE
#ifdef __cplusplus
extern "C"
{
#endif
//declare functions here
void checker();
#ifdef __cplusplus
}
#endif
#endif
and RULE_MINE.cpp
#include <bits/stdc++.h>
#include "RULE_MINE.h"
using namespace std;
void checker()
{
cout<<"whaaat?"<<endl;
}
I am compiling the following way
$ g++ RULE_MINE.h
$ g++ -c RULE_MINE.cpp
$ g++ main.c
For this, I get a compiler error
main.c:(.text+0x1947): undefined reference to 'checker'
collect2: error: ld returned 1 exit
I am unable to find what the error is. But suppose in the main.c file if I include #include "RULE_MINE.cpp" , then it is running properly and gives an output.
Can you please explain why I am getting this error?
Replace void checker() with extern "C" void checker in you cpp file to ensure correct linkage (C or cdecl linkage).
Your compilation commands are incorrect, you don't compile header files. Use:
$ g++ RULE_MINE.cpp main.c
And perhaps more flags (-W -Wall -O2 for example)
or
$ g++ -c RULE_MINE.cpp
$ g++ -c main.c # or gcc -c main.c
$ g++ RULE_MINE.o main.o
Your implementation needs extern too :
extern "C" void checker()
{
cout<<"whaaat?"<<endl;
}

undefined reference to function in gcc

I am trying to use a C static library but getting the following error while compiling/linking in gcc. The main file test.c needs to call a function from the static library libtest.a
Header file : testcplusplus.h
void print_cplusplus(int b);
testcplusplus.c :
#include <stdio.h>
#include "testcplusplus.h"
void print_cplusplus(int b) {
printf ("Value of b is %d \n",b);
}
Main C file : test.c
#include <stdio.h>
#include "testcplusplus.h"
int main() {
int a = 2 ;
print_cplusplus(a);
}
Commands Used :
g++ -c -o testcplusplus.o testcplusplus.c
ar rvs libtest.a testcplusplus.o
gcc -o test test.c -L. -ltest **// Error comes here**
Error:
In function `main':
test.c:(.text+0x15): undefined reference to `print_cplusplus'
collect2: ld returned 1 exit status
You only specify function parameter types when you declare/define the function, not when you call it. The function call should look like
print_cplusplus(a);
You also need to include testcplusplus.h from test.c so that the declaration is available when you call it. The return type of main needs to be int; and print_cplusplus should either have void return type, or should return a value.
Finally, you'll need to declare the function extern "C" for it to be callable from a C program - but only when compiling C++.
// testcplusplus.h
#ifdef __cplusplus
extern "C" {
#endif
void print_cplusplus(int b);
#ifdef __cplusplus
}
#endif
You don't rewrite a variables type when you use it, it's only used in declarations:
print_cplusplus(a);

g++ linking against static library [duplicate]

This question already has answers here:
"undefined reference" when linking against a static library
(4 answers)
Closed 8 years ago.
my main.cpp:
#include <iostream>
int foo(int arg);
using namespace std;
int main()
{
int x = foo(22);
cout << x;
return 0;
}
compile command line (Ubuntu 13.10):
g++-4.8 -L. -lfoo main.cpp -o main_app
libfoo.a contains int foo(int)
but I always get the same compiler error:
/tmp/cciAyTSP.o: In function `main':
main.cpp:(.text+0x19): undefined reference to `foo(int)'
collect2: error: ld returned 1 exit status
Of course it's impossible to be sure without a reproducible case, but a common error is that if the function foo is written in C then you need to put
extern "C" { int foo(int); }
in the .h file for the C++ program to let it know that the function was not written in C++.
To write a cross-language header file that will be good for both C and C++ the common approach is
#ifdef __cplusplus
extern "C" {
#endif
... C declarations ...
#ifdef __cplusplus
}
#endif
In addition to 6502's answer and Xephon's suggestion, also be aware that the order of the options matter. Instead of:
g++-4.8 -L. -lfoo main.cpp -o main_app
You should write:
g++-4.8 main.cpp -o main_app -L. -lfoo
That's because ld is a single pass linker. It won't revisit library libfoo to use a symbol from it for main_app.o.