I have a namespace like:
HW.h
#include <select.h>
namespace Hw
{
void setInput(uint8_t type, uint8_t input, ESelect select);
void setParam(uint8_t param, ESelect select);
}
select.h
enum class ESelect
{
Select0,
Select1,
Select2
}
Both of the above are in the same static library. I try to call this from another static library, like this.
Test.cpp
#include<HW.h>
#include<select.h>
Hw::setInput( 0, 2, ESelect::Select0 );
I get the error:
error: ‘Hw’ has not been declared
error: ‘ESelect’ has not been declared
What can be wrong?
Using #include <some_header.h> causes the compiler to search the system include directories before any user directories. Many *nix systems have a system header called select.h already, so you are probably including that instead of your own select.h.
Change all occurrences of:
#include <select.h>
to:
#include "select.h"
Ditto for #include <HW.h>.
Ideally you should not use system header names for your own headers, and you should always use "" for user headers and <> for system headers.
For future reference, a useful technique for debugging such problems is to use g++ -E ... or equivalent to see what headers are actually being included.
Looks like you do not have
#include "HW.h"
in Test.cpp
Related
I use SimpleINI library on Linux. There is the following comment:
// Defines the conversion classes for different libraries. Before including
// SimpleIni.h, set the converter that you wish you use by defining one of the
// following symbols.
//
// SI_NO_CONVERSION Do not make the "W" wide character version of the
// library available. Only CSimpleIniA etc is defined.
// SI_CONVERT_GENERIC Use the Unicode reference conversion library in
// the accompanying files ConvertUTF.h/c
// SI_CONVERT_ICU Use the IBM ICU conversion library. Requires
// ICU headers on include path and icuuc.lib
// SI_CONVERT_WIN32 Use the Win32 API functions for conversion.
When I try to compile the following code:
#define SI_NO_CONVERSION
#include "SimpleIni.h"
int main()
{
CSimpleIni ini;
return 0;
}
I get the compilation error: ‘CSimpleIniA’ was not declared in this scope It looks like SI_NO_CONVERSION is not defined in SimpleIni.h. Could you explain what's going on ?
SimpleIni.h only defines SI_Case and SI_NoCase when either of SI_CONVERT_GENERIC, SI_CONVERT_ICU or SI_CONVERT_WIN32 is defined. This leaves SI_Case and SI_NoCase undefined when (only) SI_NO_CONVERSION is defined, which causes the CSimpleIniTempl template instantiation to fail, with the related compile errors. This is an oversight/bug in the library and should be reported to the author.
As a workaround, adding the missing definitions before #include "SimpleIni.h" gets the code to compile.
#define SI_NO_CONVERSION
#define SI_Case SI_GenericCase // ***
#define SI_NoCase SI_GenericNoCase // ***
#include "SimpleIni.h"
// ... etc ...
The doc you included says it all:
Only CSimpleIniA etc is defined [when SI_NO_CONVERSION is defined].
Below is an edited version of the first example in the README.md. The SI_ASSERT macro is defined in the header file but the ASSERT_EQ and ASSERT_STREQ macros, referenced in the example, are not. It's almost unforgivable that someone's examples don't compile.
As I mentioned in a comment, this is not a well-maintained project. The instructions for building and testing don't work in a very obvious way. Seems like the developer has files in his working copy that aren't in the git repository. Inexcusable.
Additionally, I get extra compilation errors when I define SI_NO_CONVERSION. Don't use this project. Use something else instead.
#include "SimpleIni.h"
int main () {
CSimpleIniA ini;
ini.SetUnicode();
SI_Error rc = ini.LoadFile("example.ini");
if (rc < 0) { /* handle error */ };
const char* pv;
pv = ini.GetValue("section", "key", "default");
ini.SetValue("section", "key", "newvalue");
pv = ini.GetValue("section", "key", "default");
}
You compile this with something like g++.
I just feel weird about how does that work ?
That my first time that I've ever seen that , two c++ files located in the same directory "Test1.cpp,Test2.cpp"
Test1.cpp :
#include <iostream>
void magic();
int main(){
magic();
return 0;
}
Test2.cpp :
#include <iostream>
using namespace std;
void magic(){
cout << "That's not a magic , it's a logical thing.." << endl;
}
As I mentioned above , they are in the same directory , with prototype of 'magic' function.
Now my question is , how does magic work without any inclusion of Test2.cpp ?
Does C++ include it by default ? if that's true , then why do we need to include our classes ? why do we need header file while cpp file can does its purpose ?
In order to obtain an executable from a C++ source code two main phases are required:
compilation phase;
linking phase.
The first one searches only for the signature of the functions and check if the function call is compatible with the found declarations.
The second one searches the implementation of the function among the libraries or objects linked through the options specified through command line of the linker (some compilers can automatically run the linker adding some command line options).
So you need to understand the compiler and linker options in order to understand this process.
The main catch of headers file is simplifying writing of code.
Let's think about next example:
test2.cpp
#include <iostream>
using namespace std;
void my ()
{ magic(); } // here we don't know what magic() is and compiler will complain
void magic(){
cout << "That's not a magic , it's a logical thing.." << endl;
}
This code gives next error:
gaal#linux-t420:~/Downloads> g++ test2.cpp
test2.cpp: In function ‘void my()’:
test2.cpp:6:9: error: ‘magic’ was not declared in this scope
{ magic(); } // here we don't know what magic() is and compiler will complain
^
To avoid this error we need to place declaration of magic() function before definition of my(). So it is good idea to place ALL declarations in one place. Header file is a such place. If we don't use headers, we'll need to paste declaration of magic() function in any cpp-file where it will be used.
I'm trying to compile a project that has the following header:locale.h;
locale.h:
class LOG4CXX_EXPORT Locale
{
public:
...
protected:
Locale(const Locale&);
Locale& operator=(const Locale&);
const LogString language; <-- error
const LogString country; <-- error
const LogString variant; <-- error
}; // class Locale
Could anyone give me some suggestions ?
I'm getting this error. I am not sure
what is the problem.
/LOGGER/include/log4cxx/helpers/locale.h:42:41: error: field ‘language’ has incomplete type
const LogString language;
^
/LOGGER/include/log4cxx/helpers/locale.h:43:41: error: field ‘country’ has incomplete type
const LogString country;
^
/LOGGER/include/log4cxx/helpers/locale.h:44:41: error: field ‘variant’ has incomplete type
Consider the following code:
class MyClass;
int method1(const MyClass& param);
MyClass& method2();
const MyClass instance; // <- error here
The declaration of MyClass is a forward declaration. All the compiler know is that the class exists (it doesn't know its members, size...), that's why it is called an incomplete type. You can use references or pointers of that class, but that's it. See more info here When can I use a forward declaration?
So it seems that in your code, you only have a forward declaration of LogString type, and not a full declaration. Check your include files and include order so you get the full declaration of this class.
You are using std::basic_string, but there is no include for the appropriate header file:
#include <string>
What AnT wrote in a comment is the solution to the problem:
<clocale> is including your <locale.h> instead of the system one it ought to do; your locale is trying to include <string>, which again includes <clocale>.
So in the end, you get a circular include as I described in your other question https://stackoverflow.com/questions/32379927/header-file-does-not-compile-locale-h, just the chain being longer...
You need to break this inclusion circle. You can do this by removing the directory the file resides in from the inclusion directories you pass to gcc (I suppose this is -I"/LOGGER/include/log4cxx/helpers"). Instead, you can give a path to the parent directory (-I"/LOGGER/include/"). Instead of #include <locale.h> you would have to use #include <log4cxx/helpers/locale.h>.
Actually, I recommend keeping "/LOGGER/include" as the only directory you give gcc and have all other files you need included via the corresponding subpath - provided the rest of the log4cxx files allow that (which I would assume).
Apart from that, the only other way to solve the problem is indeed renaming your 'locale.h' file to something else (apart from changine the include path division, such as -I"/LOGGER/include/log4cxx" and #include <helpers/locale.h>; the one I chose, however, is the most natural one IMO).
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.
I have a file called playback_type.h with only this code in it:
#include <iostream>
enum playback_type {
NOTE_PB, SONG_PB
};
Xcode lets me include the file fine, it even autocompletes the filename but when I try to build it I'm getting all sorts of errors.
#include <playback_type.h> // Error: `playback_type.h` file not found
class PlaybackHelper{
private:
// Singleton methods
PlaybackHelper();
PlaybackHelper(PlaybackHelper const&);
void operator=(PlaybackHelper const&);
playback_type type; // Error: 'playback_type' does not name a type
public:
void setPlaybackType(playback_type aType); // Error: 'playback_type' has not been defined
//singletong method
static PlaybackHelper &getInstance();
}
Any ideas why I'm getting those erros? The .h file is included correctly, xcode helps me autocomplete it so it should be there.
Angle brackets (<>) are used do indicate system headers, and quotes ("") to indicate local headers. Usually, the preprocessor will look for local headers in your project directory, but won't look for system headers there unless you specifically tell it to. So you should use quotes for your own headers:
#include "playback_type.h"
Just replace with #include "playback_type.h"