views:

2198

answers:

10

This is a multiple question for the same pre-processing instruction.

1 - <> or "" ?

Appart from the info found in the MSDN:

http://msdn.microsoft.com/en-us/library/36k2cdd4(VS.80).aspx

1.a: What are the differences between the two notations?
1.b: Do all compilers implement them the same way?
1.c: When would you use the <>, and when would you use the "" (i.e. what are the criteria you would use to use one or the other for a header include)?

2 - #include {TheProject/TheHeader.hpp} or {TheHeader.hpp} ?

I've seen at least two ways of writing includes of one's project headers. Considering that you have at least 4 types of headers, that is:

  • private headers of your project?
  • headers of your project, but which are exporting symbols (and thus, "public")
  • headers of another project your module links with
  • headers of a compiler or standard library

For each kind of headers:

2.a: Would you use <> or "" ?
2.b: Would you include with {TheProject/TheHeader.hpp}, or with {TheHeader.hpp} only?

3 - Bonus

3.a: Do you work on project with sources and/or headers within a tree-like organisation (i.e., directories inside directories, as opposed to "every file in one directory") and what are the pros/cons?

+1  A: 

If I remember right.

You use the diamond for all libraries that can be found in your "path". So any library that is in the STL, or ones that you have installed. In Linux your path is usually "/usr/include", in windows I am not sure, but I would guess it is under "C:\windows".

You use the "" then to specify everything else. "my_bla.cpp" with no starting directory information will resolve to the directory your code is residing/compiling in. or you can also specify the exact location of your include with it. Like this "c:\myproj\some_code.cpp"

The type of header doesn't matter, just the location.

J.J.
Lats time I checked, there was a non-portable difference between the two, the "" include letting the compiler search in the directory of the including source, in addition to the default include directories. The non-portable part has a real difference between Visual C++ and gcc, gcc limiting itself to the including file, while Visual C++ tried that for every file in the inclusion stack...
paercebal
+5  A: 

I typically use <> for system headers and "" for project headers. As for paths, that is only neccessary if the file you want is in a sub-directory of an include path.

for example, if you need a file in /usr/include/SDL/, but only /usr/include/ is in your include path, then you could just use:

#include <SDL/whatever.h>

Also, keep in mind that unless the path you put starts with a /, it is relative to the current working directory.

EDIT TO ANSWER COMMENT: It depends, if there is only a few includes for a library, I'd just include it's subdirectory in the include path, but if the library has many headers (like dozens) then I'd prefer to just have it in a subdir that I specify. A good example of this is Linux's system headers. You use them like:

#include <sys/io.h>
#include <linux/limits.h>

etc.

EDIT TO INCLUDE ANOTHER GOOD ANSWER: also, if it is conceivable that two or more libraries provide headers by the same name, then the sub-directory solution basically gives each header a namespace.

Evan Teran
Would you prefer have only /usr/include/ in your include path and use #include <STL/whatever.h>, or have also /usr/include/SDL and then use <whatever.h>? (Please, answer in your post, not as a comment)
paercebal
@paercebal: I've answered this is my answer, but I will re-iterate it here. If more than one library has 'whatever.h' in it, then <STL/whatever.h> and <MYLIB/whatever.h> works nicely.
Trent
@Trent, that is another good reason basically giving each header a "namespace"
Evan Teran
The SDL example is a bad one. The reason why includes are in subdirectories on Linux is that so its possible to have different versions the same library installed. Using <SDL/...> would trash that setup. The correct way to deal with the situation is to use `sdl-config --cflags` and adding /usr/include/SDL to the include path and then just including <SDL.h>. For other libraries there are similar *-config programs and there is the generic solution which is pkg-config.
Grumbel
A: 

I use <...> from system header file (stdio, iostreams, string etc), and "..." for headers specific to that project.

James Curran
And what about headers from non-system projects/module your project happens to link with (e.g. another project produced by your team)? (Please, answer in your post, not as a comment)
paercebal
A: 

There are two primary differences between <> and "". The first is which character will end the name - there are no escape sequences in header names, and so you may be forced to do #include or "bla>file.cpp". That probably won't come up often, though. The other difference is that system includes aren't supposed to occur on "", just <>. So #include "iostream" is not guaranteed to work; #include is. My personal preference is to use "" for files that are part of the project, and <> for files that aren't. Some people only use <> for standard library headers and "" for all else. Some people even use <> only for Boost and std; it depends on the project. Like all style aspects, the most important thing is to be consistent.

As for the path, an external library will specify the convention for headers; e.g. . In a local project, I would write all paths relative to the top-level srcdir (or in a library project where they are different, the include directory).

When writing a library, you may also find it helpful to use <> to differentiate between private and public headers, or to not -I the source directory, but the directory above, so you #include "public_header.hpp" and "src/private_header.hpp". It's really up to you.

EDIT: As for projects with directory structures, I would highly recommend them. Imagine if all of boost were in one directory (and no subnamespaces)! Directory structure is good because it lets you find files easier, and it allows you more flexibility in naming ("module_text_processor.hpp" as opposed to "module/text_processor.hpp"). The latter is more natural and easier to use.

coppro
+1  A: 

I'll tackle the second part of your question:

I normally use <project/libHeader.h> when I am including headers from a 3rd party. And "myHeader.h" when including headers from within the project.

The reason I use <project/libHeader.h> instead of <libHeader.h> is because it's possible that more than one library has a "libHeader.h" file. In order to include them both you need the library name as part of the included filename.

Trent
+1  A: 

To quote from the C99 standard (at a glance the wording appears to be identical in the C90 standard, but I can't cut-n-paste from that):

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 searched 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 > characters, if any) from the original directive.

So the locations searched by #include "whatever" is a super-set of the locations searched by #include <whatever>. The intent is that the first style would be used for headers that in general "belong" to you, and the second method would be used for headers that "belong" to the compiler/environment. Of course, there are often some grey areas - which should you use for Boost headers, for example? I'd use #include <>, but I wouldn't argue too much if someone else on my team wanted #include "".

In practice, I don't think anyone pays much attention to which form is used as long as the build doesn't break. I certainly don't recall it ever being mentioned in a code review (or otherwise, even).

Michael Burr
A: 

We use #include "header.h" for headers local to the project and #include for system includes, third party includes, and other projects in the solution. We use Visual Studio, and it's much easier to use the project directory in a header include, this way whenever we create a new project, we only have to specify the include path for the directory containing all the project directories, not a separate path for each project.

Brian Stewart
A: 

1.a: What are the differences between the two notations?

"" starts search in the directory where C/C++ file is located. <> starts search in -I directories and in default locations (such as /usr/include). Both of them ultimately search the same set of locations, only the order is different.

1.b: Do all compilers implement them the same way?

I hope so, but I am not sure.

1.c: When would you use the <>, and when would you use the "" (i.e. what are the criteria you would use to use one or the other for a header include)?

I use "" when the include file is supposed to be next to C file, <> in all other cases. IN particular, in our project all "public" include files are in project/include directory, so I use <> for them.

2 - #include {TheProject/TheHeader.hpp} or {TheHeader.hpp} ?

As already pointed out, xxx/filename.h allows you to do things like diskio/ErrorCodes.h and netio/ErrorCodes.h

* private headers of your project?

Private header of my subsystem in project. Use "filename.h" Public header of my subsystem in project (not visible outside the project, but accessible to other subsystems). Use or , depending on the convention adapted for the project. I'd rather use

* headers of your project, but which are exporting symbols (and thus, "public")

include exactly like the users of your library would include them. Probably

* headers of another project your module links with

Determined by the project, but certainly using <> * headers of a compiler or standard library Definitely <>, according to standard.

3.a: Do you work on project with sources and/or headers within a tree-like organisation (i.e., directories inside directories, as opposed to "every file in one directory") and what are the pros/cons?

I do work on a structured project. As soon as you have more than a score of files, some division will become apparent. You should go the way the code is pulling you.

Arkadiy
A: 

Re <> vs "". At my shop, I'm very hands-off as far as matters of "style" are concerned. One of the few areas where I have a requirement is with the use of angle brackets in #include statements -- the rule is this: if you are #including an operating system or compiler file, you may use angle brackets if appropriate. In all other cases, they are forbidden. If you are #including a file written either by someone here or a 3rd party library, <> is forbidden.

The reason is this: #include "x.h" and #include don't search the same paths. #include will only search the system path and whatever you have -i'ed in. Importantly, it will not search the path where the file x.h is located, if that directory isn't included in the search path in some other way.

For example, suppose you have the following files:

c:\dev\angles\main.cpp

#include "c:\utils\mylib\mylibrary.h"

int main()
{
    return 0;
}

c:\utils\mylib\mylibrary.h

#ifndef MYLIB_H
#define MYLIB_H

#include <speech.h>

namespace mylib
{
    void Speak(SpeechType speechType); 
};

#endif

c:\utils\mhlib\speech.h

#ifndef SPEECH_H
#define SPEECH_H

namespace mylib
{
    enum SpeechType {Bark, Growl};
};

#endif

This will not compile without changing the path either by setting the PATH environment variable or -i'ing in the c:\utils\mhlib\ directory. The compiler won't be able to resove #include <speech.h> even though that file is in the same directory as mylibrary.h!

We make extensive use of relative and absolute pathnames in #include statements in our code, for two reasons.

1) By keeping libraries and components off the main source tree (ie, putting utility libraries in a special directory), we don;t couple the lifecycle of the library to the lifecycle of the application. This is particularly important when you have several distinct products that use common libraries.

2) We use Junctions to map a physical location on the hard drive to a directory on a logical drive, and then use a fully-qualified path on the logical drive in all #includes. For example:

#include "x:\utils\mylib.h" -- good, x: is a subst'ed drive, and x:\utils points to c:\code\utils_1.0 on the hard drive

#include "c:\utils_1.0\mylib.h" -- bad! the application tha t#includes mylib.h is now coupled to a specific version of the MYLIB library, and all developers must have it on the same directory on thier hard drive, c:\utils_1.0

Finally, a broad but difficult to achieve goal of my team is to be able to support 1-click compiles. This includes being able to compile the main source tree by doing nothing more than getting code from source control and then hitting 'compile'. In particular, I abhor having to set paths & machine-wide #include directories in order to be able to compile, because every little additional step you add to the set-up phase in buildign a development machine just makes it harder, easier to mess up, and it takes longer to get a new machine up to speed & generating code.

John Dibling
+7  A: 

After reading all answers, as well as compiler documentation, I decided I would follow the following standard.

For all files, be them project headers or external headers, always use the pattern:

#include <namespace/header.hpp>

The namespace being at least one directory deep, to avoid collision.

Of course, this means that the project directory where the project headers are should be added as "default include header" to the makefile, too.

The reason for this choice is that I found the following information:

1. The include "" pattern is compiler-dependent

I'll give the answers below

1.a Visual C++:

Source:

#include "MyFile.hpp"

The preprocessor searches for include files in the following order:

  1. In the same directory as the file that contains the #include statement.
  2. In the directories of any previously opened include files in the reverse order in which they were opened. The search starts from the directory of the include file that was opened last and continues through the directory of the include file that was opened first.
  3. Along the path specified by each /I compiler option.
  4. Along the paths specified by the INCLUDE environment variable.

#include <MyFile.hpp>

The preprocessor searches for include files in the following order:

  1. Along the path specified by each /I compiler option.
  2. When compiling from the command line, along the paths that are specified by the INCLUDE environment variable.

1.b g++

Source:

#include "MyFile.hpp"

This variant is used for header files of your own program. The preprocessor searches for include files in the following order:

  1. In the same directory as the file that contains the #include statement.
  2. Along the path specified by each -iquote compiler option.
  3. in the quote directories
  4. As for the #include

#include <MyFile.hpp>

This variant is used for system header files. The preprocessor searches for include files in the following order:

  1. Along the path specified by each -I compiler option.
  2. Inside the system directories.

1.c Conclusion

The pattern "" could lead to subtle compilation error across compilers, and as I currently work both on Windows Visual C++, Linux g++, and Solaris CC, this is not acceptable.

Anyway, the advantage of "" described features are far from interesting anyway, so...

2. Use the {namespace}/header.hpp pattern

I saw at work (i.e. this is not theory, this is real-life, painful professional experience) two headers with the same name, one in the local project directory, and the other in the global include.

As we were using the "" pattern, and that file was included both in local headers and global headers, there was no way to understand what was really going on, when strange errors appeared.

Using the directory in the include would have saved us time because the user would have had to either write:

#include <MyLocalProject/Header.hpp>

or

#include <GlobalInclude/Header.hpp>

You'll note that while

#include "Header.hpp"

would have compiled successfully, thus, still hiding the problem, whereas

#include <Header.hpp>

would not have compiled in normal circonstances.

Thus, sticking to the <> notation would have made mandatory for the developer the prefixing of the include with the right directory, another reason to prefer <> to "".

3. Conclusion

Using both the <> notation and namespaced notation together removes from the pre-compiler the possibility to guess for files, instead searching only the default include directories.

Of course, the standard libraries are still included as usual, that is:

#include <cstdlib>
#include <vector>
paercebal