-
March 29th, 2010, 11:59 PM
#1
Type not found problems
Hi all,
I'm having some rather odd problems with includes. I declare and define a class, along with some methods, in one header file. (They are in a namespace) I then include that header file in numerous other files. In one of the files it's included in (another header file), none of the methods/typedefs/classes defined in the header file can be found, but in all other files, everything is found properly. I'm sure it has nothing to do with the fact the everything is in a namespace, because when I remove the namespace (make everything part of the global namespace), nothing changes.
Here are some code fragments... I can't post all of it, because it's a large project, and I haven't been able to reproduce it anywhere else, so no SSCCE either
io.hpp//the main file where the class/typedef/methods are defined
Code:
namespace io{
typedef int IChar;
class InputData{
std::istream * inStream;
std::string fileName;
int onCharNum;
public:
InputData(std::istream* stream, std::string filename,
int cNum);
InputData(std::string fileName);
InputData(std::string fileName, int cNum);
~InputData();
IChar read();
std::string readToDelim(char delim='\n');
int getCharNumber(){return onCharNum;}
std::string getFileName(){return fileName;}
};
...//some other methods
}//close namespace
objManage.hpp//the header file where the types cannot be found
Code:
#include <list>
#include <map>
#include <string>
#include <iostream>
#include "io.hpp"
#include "../shared/opcode.hpp"
#include "osdep/threading.hpp"
...//forward declarations of structs and classes
struct MethodLocation{
std::string fileName;
int cNumber;
MethodLocation(io::InputData* copyPos);//believes io::InputData does not exist
MethodLocation(std::string fName,int cNumber);
};
class Method{
public:
Method();
virtual ~Method();
virtual void call(Variable* params=NULL, int params=0);
std::string getName(){return name;}
TypeData getType(){return returnType;}
std::list<VariableBase> getParams(){return params;};
protected:
Method(std::string name,TypeData returnType);
std::string name;
TypeData returnType;
std::list<VariableBase> params;
private:
io::InputData* input;//doesn't think that io::InputData exists
MethodLocation* inProvider;
bool reloading;
Notifier* reloadWait;
Lock* reloadLock;
static void reload(void* modMethod);
void setReload(bool reload);
};
I realize that there isn't really any way to understand what the code is actually doing, but as I said, if I tried to post the whole code, it would be a mess. However, the code is in the Subversion repository at https://arlix.svn.sourceforge.net/svnroot/arlix if you want to take a look, and I am willing to post any additional code that might be needed.
I'm using the MinGW port of g++ as my compiler, under Eclipse CDT.
Thanks in advance,
Singing Boyo
[edit]
What do you know, SVN repositories can be viewed via a regular browser, at least on Sourceforge. So, here's a bit more information on the repository - the files are under trunk/src/vm.
Also, the code is Win32 dependent for full compilation.
Thanks again
[/edit]
Last edited by Singing Boyo; March 30th, 2010 at 08:42 PM.
-
March 30th, 2010, 12:33 AM
#2
Re: Type not found problems
Originally Posted by Singing Boyo
Here are some code fragments... I can't post all of it, because it's a large project, and I have been able to reproduce it anywhere else, so no SSCCE either
First thing is that your io.hpp file should compile "by itself" without any help from header files included in other modules. I don't see <string> or <fstream> included in io.hpp.
I also don't see any include guards on the headers, so there is no protection if that header file is included twice somewhere.
Fix these issues first, then #include io.hpp in an empty source file, and compile that source file. If that empty source file doesn't compile, you need to fix io.hpp so that it compiles.
Regards,
Paul McKenzie
-
March 30th, 2010, 08:48 PM
#3
Re: Type not found problems
Sorry, I should have been more clear...
The code I posted is only part of the full code. I have header guards, required include files, etc, in the files already, and io.hpp compiles fine with all other files that use it.
Also, in reading the part of it you quoted, I noted a rather horrible typo... have been able to reproduce it instead of haven't been able to reproduce it.
Here are a couple of links to the complete files, because, as I said before, they are rather large altogether, and depend on other files as well, so it would be a mess if I posted all the code:
io.hpp - https://arlix.svn.sourceforge.net/sv...rlix/vm/io.hpp
objManage.hpp - https://arlix.svn.sourceforge.net/sv.../objManage.hpp
I also just realized the header guards in objManage.hpp are wrong - it was originally called omhandler.hpp, and I forgot to go through and change them when I renamed it.
-
March 30th, 2010, 10:12 PM
#4
Re: Type not found problems
Originally Posted by Singing Boyo
Sorry, I should have been more clear...
The code I posted is only part of the full code. I have header guards, required include files, etc, in the files already, and io.hpp compiles fine with all other files that use it.
Then slowly start with no headers, add a header at a time until the problem appears. Then whatever you did last is what is causing the problem.
Regards,
Paul McKenzie
-
March 30th, 2010, 11:17 PM
#5
Re: Type not found problems
Your problem is a classic circular dependency. I suspected as much from the description, but looking at those links confirms it: io.hpp includes objManage.hpp, and objManage.hpp includes io.hpp.
Since a #include is basically the same as a copy/paste, what you're getting is that, due to their include guards, only one of the files can be pasted into the other. When you try to paste the first one again, you're already inside the include guards of the first one, so you don't get another copy.
The solution is to remove the #include from one of the two files. Which one is up to you. You can still declare references and pointers to the classes from the removed include via forward declares, but you can't do anything with those classes that requires knowing the definition. You move the portions of the logic which need the definition out of the header and into a source file, and the source file can safely #include both headers.
Personally, I like to minimize the #includes in header files (and maximize the usage of forward-declarations instead), since not only does it avoid these problems but it also speeds up compiles.
-
March 31st, 2010, 12:04 AM
#6
Re: Type not found problems
Thanks Lindley, solved the problem perfectly. It's one of those things that, being mostly a Java programmer until now, I just haven't run into.
I'm still a bit confused though... I would have thought that BECAUSE #include is basically copy/paste, you would get this being processed by the compiler:
Code:
#ifndef HEADER1GUARD
#define HEADER1GUARD
//below is an extension of #include Header2
#ifndef HEADER2GUARD
#define HEADER2GUARD
//then again includes Header 1
#ifndef HEADER1GUARD
#define HEADER1GUARD
//This time it doesn't take the include of Header 2
//because HEADER1GUARD is already defined...
//At least I would expect this, it's obviously not happening
#endif
#endif
#endif
Since this doesn't happen, I'm assuming that compilers process the code from includes even if they are within a section of code that is not processed due to pre-processor directives?
Thanks,
Singing Boyo
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|