Sign in to follow this  
Wooh

[C++] Put some code files in subdirs?

Recommended Posts

The list of files in my project is getting quite big and it is hard find the file I'm looking for. I guess I could put some files in a subdirectories but how do I do this in the best way? I think I should group files that belongs together into the same directory like graphic/, serialization/ and so on but how will I include it from other files later? Say I want to include the sprite class in a file from parent directory, I could write:
#include "graphic/sprite.h"
My concern with this is that if I want to use some other file that's in another directory I get a lot of ugly things like ".." in the path.
#include "../some_other_dir/foo.h"
Also if I move one file to another directory I will have to change the include for all files that uses it. I think I have seen other projects that uses directories but just includes the file name. Is this to recommend? And how is it accomplished?

Share this post


Link to post
Share on other sites
Quote:
My concern with this is that if I want to use some other file that's in another directory I get a lot of ugly things like ".." in the path.
*** Source Snippet Removed ***
You shouldn't have to use "..".
There's two types of include directives in C/C++.
#include "path/relative/to/current/file"
#include <path/relative/to/project>

e.g. say you've got the following directory structure:
/project
/project/graphics
/project/physics
Then a file, such as /project/graphics/sprite.h can look like:
#include "spriteHelpers.h"       // opens /project/graphics/spriteHelpers.h
#include <physics/boundingBox.h> // opens /project/physics/boundingBox.h
Quote:
Also if I move one file to another directory I will have to change the include for all files that uses it.
This isn't really a problem in my experience. e.g. How often do you move a graphics file into the physics directory, etc?

Share this post


Link to post
Share on other sites
Sounds good Hodgman but if I use <> it does not find the file to include.

I have always used <> for std:: files, and "" for my own files. Is it a good idea to mix or should I always use <> to be consistent?

Share this post


Link to post
Share on other sites
You could add your main project source directory as an include search path, so when you do include <physics/boundingBox.h>, it will look in your main directory, find the directory physics and then find the file you were looking for.

Share this post


Link to post
Share on other sites
Hodgman has this one incorrect. "" searches for local files, and <> searches for local or system include files. There is no way to specify "relative to project root", because C++ does not have the concept of a "project".

What I generally do is add my project root source directory to the system includes, so all my paths can be relative to this root and I don't need to use directory climbing.

Share this post


Link to post
Share on other sites
Quote:
Original post by rip-off
Hodgman has this one incorrect. "" searches for local files, and <> searches for local or system include files.

Hmm?
Quote:
From the C++ Standard, Section 16.2, paragraphs 2 and 3
A preprocessing directive of the form

# include <h-char-sequence> new-line

search a sequence of implementation-defined places for a header identified uniquely by the specified sequence between the < and > delimiters, and causes the replacement of that directive by the entire contents of the header. How the places are specified or the header identified is implementation-defined.

A preprocessing directive of the form

# include "q-char-sequence" new-line

causes the replacement of that directive by the entire contents of the source file identified by the specified sequence between the " delimiters. The named source file is search for in an implementation-defined manner. If this search is not supported, or if the search fails, the directive is reprocessed as if it read

# include <h-char-sequence> new-line

with the identical contained sequence (including the > characters, if any) from the original directive.

Share this post


Link to post
Share on other sites
Fair enough, my mistake.

In my defense, I originally wrote it as you described. I was unsure, because I hadn't used C++ in a while. I briefly tested it in MSVC and it appeared to work as I described, so I assumed that that was the standard behvaiour. Odd.

Share this post


Link to post
Share on other sites
Quote:
Original post by Wooh
Also if I move one file to another directory I will have to change the include for all files that uses it.
Yep, that happens with both file-relative and root-relative paths unfortunately.

What I do is set the project's root folder as an include search path, then files include like so:
#include "project/subsystem/somefolder/file.hpp"

I try to keep the directory structure pretty broad and shallow, you don't want to be in a position where the structure is so deep and specific that slight shifts in a file's responsibility suddenly cause it to hop from folder to folder. Unless you have decent refactoring tools this kind of thing is just another headache that you don't want to deal with; if you don't deal with it though it'll just lead to code rot.

I prefer to use folders to structure things logically as opposed to merely separating things for the sake of reducing the number of files in a folder so that I can find them faster. In the latter case I find Visual Studio's filters pretty useful. If for whatever reason you don't want any paths in your #includes then you could just have all the files in the project's root and just structure things with filters so you can find them as easily as with real folders.

Share this post


Link to post
Share on other sites
Thank you all for your help. I got it working now.
Quote:
Original post by SiCrane
Quote:
From the C++ Standard, Section 16.2, paragraphs 2 and 3
A preprocessing directive of the form

# include <h-char-sequence> new-line

search a sequence of implementation-defined places for a header identified uniquely by the specified sequence between the < and > delimiters, and causes the replacement of that directive by the entire contents of the header. How the places are specified or the header identified is implementation-defined.

A preprocessing directive of the form

# include "q-char-sequence" new-line

causes the replacement of that directive by the entire contents of the source file identified by the specified sequence between the " delimiters. The named source file is search for in an implementation-defined manner. If this search is not supported, or if the search fails, the directive is reprocessed as if it read

# include <h-char-sequence> new-line

with the identical contained sequence (including the > characters, if any) from the original directive.
So there is no need to use <>? I can use "" always for my own files, nice :)

Share this post


Link to post
Share on other sites
Quote:
Original post by dmatter
Yep, that happens with both file-relative and root-relative paths unfortunately.

I've worked on projects where all project subfolders were recursively added to the search path. We had a fairly extensive directory structure, but we just used <> and filenames for our includes. Thus we could use directories to organize the files in our project, but our #includes would still act as if we had our entire project in a single directory.

Obviously, that comes with the limitation of requiring unique names for source files even if they are in different directories. There may have also been other limitations that I did not encounter (and if you know of any, I'd love a warning). But nevertheless it was nice to have the code entirely decoupled from the directory structure.

Share this post


Link to post
Share on other sites
Quote:
Original post by rip-off
I briefly tested it in MSVC and it appeared to work as I described, so I assumed that that was the standard behvaiour. Odd.
Huh, I thought that was the standard behaviour too :(
And yeah by project root I meant the include directories that are specified for the project, not that it matters now after being struck by SiCrane's std::hammer ;)

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this