Implementation of function not needed and no warning given [duplicate] - c++

This question already has answers here:
Is there a way to get warned about unused functions?
(6 answers)
Closed 8 years ago.
I am wondering if there are any compiler flags you can set to pick up this case. Say I have the following files:
a.h
class a
{
public:
int lala(void);
int lala2(void);
};
a.cpp
#include "a.h"
int a::lala(void)
{
return 5;
}
main.cpp
#include <iostream>
#include "a.h"
int main()
{
a thi;
std::cout << thi.lala() << std::endl;
return 0;
}
The problem here is that the function lala2 is not implemented and although its not used not even a warning is issued.
So i don't know how it led to this but basically in a large portion of code there was an un-implemented function. I am just wondering if there are any compiler flags that will allow us to pick this up? Using g++ -pedantic -Wall was not enough.

The compiler can't do that. The compiler compiles source files one by one. You may have the implementation of lala in one source file and of lala2 in another. The compiler has no way of knowing whether there's a lala2 implementation somewhere else.
The linker will display an error if you try to use lala2. If you don't, the code will just work.

Related

Error: Multiple definitions of function in C++ class [duplicate]

This question already has answers here:
Separating class code into a header and cpp file
(8 answers)
Closed 5 months ago.
I don't know how to add functions of a class outside its scope to it, use them in another class and then compile it.
MyMain.cpp
#include"MyClass.cpp"
int main(){
MyClass myClass;
myClass.run();
}
MyClass.cpp
#ifndef MYCLASS_CPP
#define MYCLASS_CPP
#include<iostream>
class MyClass {
private:
void usage();
public:
void run();
};
void MyClass::usage(){
std::cout << "usage called" << std::endl;
}
void MyClass::run(){
usage();
}
#endif
I try to compile it with:
g++ MyMain.cpp MyClass.cpp -o main
With that I get the following error message:
/usr/bin/ld: /tmp/ccN7GfOD.o: in function `MyClass::usage()':
MyClass.cpp:(.text+0x0): multiple definition of `MyClass::usage()'; /tmp/ccLhxS6v.o:MyMain.cpp:(.text+0x0): first defined here
/usr/bin/ld: /tmp/ccN7GfOD.o: in function `MyClass::run()':
MyClass.cpp:(.text+0x38): multiple definition of `MyClass::run()'; /tmp/ccLhxS6v.o:MyMain.cpp:(.text+0x38): first defined here
collect2: error: ld returned 1 exit status
If I have understood the concept correctly, the function headers within the class serve only as placeholders. The actual functionality is then "overwritten" by the external functions, which also contain a body.
And why does the error message say, that the function is already defined in the MyMain.cpp?
I have also seen that there are many similar questions here, but unfortunately I could not expand my understanding of the basic problem to solve it.
Is it possible that I am using the command to build the class with C++ incorrectly or that I can save the #include "MyClass.cpp"?
Kind regards
Several things wrong. here's the steps to put it right
Rename MyClass.cpp to MyClass.h.
Create a new empty file MyClass.cpp
Move the function definitions MyClass::usage() { .. } and MyClass::run() { .. } from MyClass.h to MyClass.cpp. You should probably also move #include <iostream> but this is not essential.
Add #include "MyClass.h" to MyClass.cpp
Change #include "MyClass.cpp" to #include "MyClass.h" in MyMain.cpp
Then build as you are doing now. That part is correct.
Essentially the technique is to separate your code into declarations and definitions. The declarations go into header files, which are included in the cpp files. The cpp files contain the definitions and are what you compile.

constexpr data member defined in .h is unresolved in .cpp only on -std=c++14 and below [duplicate]

This question already has answers here:
constexpr static member before/after C++17
(1 answer)
Defining static const integer members in class definition
(7 answers)
Closed 4 years ago.
The following only links successfully with -std=c++17 or above. -std=c++14 or below gives an unresolved external error:
In function `C::f()':
C.cpp:(.text+0x19): undefined reference to `C::kConstant'
Why doesn't this work with the c++14 standard and does work with the c++17 standard? (tested with both GCC and Clang)
And why does the commented-out workaround work even on c++14?
C.h
#pragma once
class C {
public:
static constexpr int kConstant = 10;
int f();
};
C.cpp
#include "C.h"
#include <algorithm>
int C::f()
{
// This only works with -std=c++17 or above
return std::min (1, kConstant);
// This works even with -std=c++14
// return std::min (1, static_cast<int> (kConstant));
}
Main.cpp
#include "C.h"
int main()
{
C c;
c.f();
}
Wandbox
Update: This question isn't an exact duplicate, but has an answer which answers most of my question. It doesn't answer why the workaround works with -std=c++14, though, and the original doesn't. Is it perhaps because in the original the variable is odr-used, and in the workaround it is not?

Why does a member function exist only once even defined in one multiple included .h file? [duplicate]

This question already has answers here:
How can a C++ header file include implementation?
(7 answers)
Closed 6 years ago.
I am just wondering how the compiler can handle the situation where a member function is declared & defined only in a include file but this .h file is included multiple times in different source codes without complains of the linker regarding multiple definition of ....
foo_1.h:
class foo
{
public:
auto in_include() -> void { printf( "in in_include()\n" ); }
foo();
};
foo_1.cpp:
#include <stdio.h>
#include "foo_1.h"
foo::foo()
{
printf( "in foo()\n" );
in_include();
}
and finally foo_main.cpp:
#include <stdio.h>
#include "foo_1.h"
int main()
{
foo fooObject;
}
These MCVE compiles and links fine and produces the expected output:
in foo()
in in_include()
BUT, when I add in foo_1.h this line int globar_var; then the linker complains [as I expect it]:
/tmp/ccfjJJAT.o:(.bss+0x0): multiple definition of `globar_var'
/tmp/cciob9sM.o:(.bss+0x0): first defined here
I do not consider as a duplicate because I ask why the linker does not complain. The other question is more or less asking why a function can be defined in a header file.
Class member functions that are defined with a body within the class declaration automatically become inline functions, and therefore it's OK even if the definition is compiled multiple times. You can get the same for non-class functions by using the inline keyword.
How this is implemented in practice is up to the compiler - it could actually inline the code every time it's called (think copy and paste), or it could arrange for some linker magic I don't fully understand to happen that prevents the collision.

Error with multiple definitions of function

I am trying to relearn C++ after taking an intro course a few years ago and I’m having some basic problems. My current problem occurs when trying to use a friend function. Here is my code in 2 files.
First:
// fun.cpp
#include <iostream>
using namespace std;
class classA {
friend void funct();
public:
classA(int a=1,int b=2):propa(a),propb(b){cout<<"constructor\n";}
private:
int propa;
int propb;
void outfun(){
cout<<"propa="<<propa<<endl<<"propb="<<propb<<endl;
}
};
void funct(){ // ERROR HERE
cout<<"enter funct"<<endl;
classA tmp(1,2);
tmp.outfun();
cout<<"exit funct"<<endl;
}
Second:
// mainfile.cpp
#include <iostream>
#include "fun.cpp"
using namespace std;
int main(int nargin,char* varargin[]) {
cout<<"call funct"<<endl;
funct();
cout<<"exit main"<<endl;
return 0;
}
The error I am getting is "multiple definition of `funct()'". Am I using the wrong syntax when declaring it as a friend function?
Here is a highly simplified but hopefully relevant view of what happens when you build your code in C++.
C++ splits the load of generating machine executable code in following different phases -
Preprocessing - This is where any macros - #defines etc you might be using get expanded.
Compiling - Each cpp file along with all the #included files in that file directly or indirectly (together called a compilation unit) is converted into machine readable object code.
This is where C++ also checks that all functions defined (i.e. containing a body in { } e.g.
void Foo( int x){ return Boo(x); }) are referring to other functions in a valid manner.
The way it does that is by insisting that you provide at least a declaration of these other functions (e.g. void Boo(int); ) before you call it so it can check that you are calling it properly among other things. This can be done either directly in the cpp file where it is called or usually in an included header file.
Note that only the machine code that corresponds to functions defined in this cpp and included files gets built as the object (binary) version of this compilation unit (e.g. Foo) and not the ones that are merely declared (e.g. Boo).
Linking - This is the stage where C++ goes hunting for stuff declared and called in each compilation unit and links it to the places where it is getting called. Now if there was no definition found of this function the linker gives up and errors out. Similarly if it finds multiple definitions of the same function signature (essentially the name and parameter types it takes) it also errors out as it considers it ambiguous and doesn't want to pick one arbitrarily.
The latter is what is happening in your case. By doing a #include of the fun.cpp file, both fun.cpp and mainfile.cpp have a definition of funct() and the linker doesn't know which one to use in your program and is complaining about it.
The fix as Vaughn mentioned above is to not include the cpp file with the definition of funct() in mainfile.cpp and instead move the declaration of funct() in a separate header file and include that in mainline.cpp. This way the compiler will get the declaration of funct() to work with and the linker would get just one definition of funct() from fun.cpp and will use it with confidence.
The problem is that if you include fun.cpp in two places in your program, you will end up defining it twice, which isn't valid.
You don't want to include cpp files. You want to include header files.
The header file should just have the class definition. The corresponding cpp file, which you will compile separately, will have the function definition.
fun.hpp:
#include <iostream>
class classA {
friend void funct();
public:
classA(int a=1,int b=2):propa(a),propb(b){std::cout<<"constructor\n";}
private:
int propa;
int propb;
void outfun(){
std::cout<<"propa="<<propa<<endl<<"propb="<<propb<< std::endl;
}
};
fun.cpp:
#include "fun.hpp"
using namespace std;
void funct(){
cout<<"enter funct"<<endl;
classA tmp(1,2);
tmp.outfun();
cout<<"exit funct"<<endl;
}
mainfile.cpp:
#include <iostream>
#include "fun.hpp"
using namespace std;
int main(int nargin,char* varargin[]) {
cout<<"call funct"<<endl;
funct();
cout<<"exit main"<<endl;
return 0;
}
Note that it is generally recommended to avoid using namespace std in header files.
This problem happens because you are calling fun.cpp instead of fun.hpp. So c++ compiler finds func.cpp definition twice and throws this error.
Change line 3 of your main.cpp file, from #include "fun.cpp" to #include "fun.hpp" .
You have #include "fun.cpp" in mainfile.cpp so compiling with:
g++ -o hw1 mainfile.cpp
will work, however if you compile by linking these together like
g++ -g -std=c++11 -Wall -pedantic -c -o fun.o fun.cpp
g++ -g -std=c++11 -Wall -pedantic -c -o mainfile.o mainfile.cpp
As they mention above, adding #include "fun.hpp" will need to be done or it won't work. However, your case with the funct() function is slightly different than my problem.
I had this issue when doing a HW assignment and the autograder compiled by the lower bash recipe, yet locally it worked using the upper bash.

C++ compiler issue (?): can't pass arguments to functions in separate class files [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
What is an undefined reference/unresolved external symbol error and how do I fix it?
I recently started working on an interpreter in C++, but I got annoyed that vectors or arrays could not be passed to external class methods no matter what I tried and so I deleted everything I had worked on. As it turns out, I can't pass even an int to another class. I decided to give C++ another chance before resorting to C or Java, but the compiler still doesn't work as I would expect. Maybe I'm forgetting something simple about C++, as I haven't used it in a while, but this seems simple enough. My problem is: I can't pass arguments to methods in other classes when they're not defined in the same file. Here's what I'm trying to do:
Main: main.cpp
#include "myclass.h"
int main() {
MyClass test;
int n = test.add(25, 30);
return n;
}
Header: myclass.h
class MyClass {
public:
int add(int a, int b);
};
Class implementation: myclass.cpp
#include "myclass.h"
int MyClass::add(int a, int b) {
return a + b;
}
Compiling this with g++ main.cpp yields
/tmp/ccAZr6EY.o: In function main':
main.cpp:(.text+0x1a): undefined reference toMyClass::add(int, int)'
collect2: error: ld returned 1 exit status
What the heck am I doing wrong? Also, the compiler yells at me for the same thing even if my functions aren't parameterized, so it must be a problem with the header.
Any help is much appreciated - thanks!
You need to compile both files
g++ main.cpp myclass.cpp
If you only compile main.cpp, the compiler finds the declaration of MyClass::add in your header but the linker later fails to find an implementation of MyClass::add to jump to.