I think some headers need to be included to compile with gcc(4.9),
#include <algorithm> // for std::transform
#include <numeric> // for std::adjacent_difference
However, I found it's not necessary include them at all, I can still call
for example, the following functions
std::adjacent_difference (V1.begin(), V1.end(), V2.begin());
std::transform(V2.begin(), V2.end(), V3.begin(), V4.begin(), std::divides<double>());
Maybe I have misunderstood the mechanism of including header files...Any hint?
It is quite typical for a header to include other headers. The headers included by header x will be included in any file that includes x. That should be trivial to understand once you grasp what including a file in another means. In this case, one of the standard headers happened to be included in another.
Files included by headers can change between versions. If you don't include a required header, your program may break under another (version of) standard library even though it may appear to work in the current implementation. Of course, this applies to other libraries as well.
The C++ standard says the following in section 17.6.5.2 [res.on.headers]:
A C++ header may include other C++ headers.
For your question, this means a compiler can just act as if you included other C++ headers. In your example, the compiler is allowed to include the <numeric> header if you include <algorithm>, or vice versa.
But that's not the whole story. The standard also says:
A C++ header shown in its synopsis as including other C++ headers
shall provide the declarations and definitions that appear in the
synopses of those other headers.
And:
The C standard headers [...] shall include only their corresponding
C++ standard header [...]
(Note that I am quoting from the last free C++11 draft. The final version of the ISO standard is not free. See https://isocpp.org/std/the-standard.)
The <utility> header is an example of a C++ header which is guaranteed to include another. Its synopsis explitly includes <initializer_list>. Which means a conforming compiler must accept the following:
#include <utility>
// #include <initializer_list> // not needed
int main()
{
std::initializer_list<int> x = {};
}
For the C headers, in contrast, this means that the following must not compile:
#include <stdio.h>
int main()
{
std::cout << "\n"; // must not compile
}
What the standard says is surely confirmed by your implementation's documentation. For example, the documentation for Visual C++ 2013 says:
A C++ library header includes any other C++ library headers it needs
to define needed types. (Always include explicitly any C++ library
headers needed in a translation unit, however, lest you guess wrong
about its actual dependencies.) A Standard C header never includes
another standard header.
The advice given here is a good one; do not depend on automatic inclusion. Explicitly include everything you need.
Related
The following program compiles correctly:
#include <algorithm>
int main(int argc, char *argv[]) {
return int(log(23.f));
}
(under g++ 4.9.2 with the flag -std=c++11)
The code uses the function log, which is defined on <cmath>. However, it does not include the header <cmath>, only the header <algorithm>. Why is it that g++ doesn't give any warnings, and compiles the code correctly?
According to the standard, some headers do include others. As an example, <cinttypes> includes <cstdint>. See the Includes section here. With respect to <algorithm>, there is no such statement as to which other headers it should include (see here). So, the conclusion is, <algorithm> is not required to include <cmath>, and your example code is not portable. It may fail to compile on other C++ implementations.
In the C++11 standard, [res.on.headers]/1 states that
A C++ header may include other C++ headers. A C++ header shall provide
the declarations and definitions that appear in its synopsis. A C++
header shown in its synopsis as including other C++ headers shall
provide the declarations and definitions that appear in the synopses
of those other headers.
Now consider [algorithms.general]/2:
Header <algorithm> synopsis
#include <initializer_list>
namespace std {
// ......
<cmath> isn't listed and clearly not included in <initializer_list>. Thus your program is not guaranteed to compile on a standard-conforming implementation. One should never rely on "implicit inclusion" - the general guideline is to include every header from which an entity is used.
Exceptions are e.g. <iostream> including <ostream>, which is guaranteed since C++11.
To answer your question:
Why is it that g++ doesn't give any warnings, and compiles the code correctly?
Because C++ implementations aren't required to and it's actually quite difficult to implement this warning given the way #include works. Attempts have been made, but there are problems that haven't been entirely addressed.
Moving to a different model can enable this kind of checking. However, in the interests of backwards compatibility and allowing the easiest possible transition the 'modularizations' of the standard library I've used happen to explicitly allow code that previously depended on indirect includes to continue to work.
You can see this, for example, in libc++'s module map; Those export * lines declare "any modules imported by this module are also exported." Which is to say, a module std.algorithm that imports a module std.cmath also exports, so anyone that imports std.algorithm also gets access to std.cmath.
For new code it would be very nice if these 'legacy exports' could be turned off, but for pre-existing large projects it is very nice to be able to just flip on -fmodules and have the project work with no changes.
Using clang's implementation of modules with libc++, and modifying the module map file to remove the non-portable, indirect include behavior, clang reports such errors like:
main.cpp:5:16: error: declaration of 'log' must be imported from module 'Darwin.C.math' before it is required
return int(log(23.f));
^
/usr/include/math.h:387:15: note: previous declaration is here
extern double log(double);
^
1 error generated.
libc++ <algorithm> doesn't include <cmath>, so I used <random> instead. Otherwise the source that produced the above is the same as what you show.
I'm collaborating with a friend using MSVC and I'm using clang. One thing I've noticed is that clang seems to be automatically including some standard headers, while MSVC is not. For example, I just used the functions assert() and round() from assert.h and math.h respectively.
The code complied fine for me without explicitly including the headers -- is there a switch to turn this behavior off? It's driving me up a wall. I want there to be an error unless I explicitly include the header.
The Standard allows standard header files to include each other, or forward declare items normally found in other files... most likely what is happening is that these definitions are being provided (directly or indirectly) by one of the headers you are including.
This behavior is Standard-conformant, so unfortunately writing portable code is going to require testing using multiple compilers.
A C++ header may include other C++ headers. A C++ header shall provide the declarations and definitions that appear in its synopsis. A C++ header shown in its synopsis as including other C++ headers shall provide the declarations and definitions that appear in the synopses of those other headers.
Certain types and macros are defined in more than one header. Every such entity shall be defined such that any header that defines it may be included after any other header that also defines it (3.2).
The C standard headers (D.5) shall include only their corresponding C++ standard header, as described in 17.6.1.2.
In addition to headers included by other headers, there's also the fact that the C++ headers may or may not introduce global names, while the C headers may or may not introduce names inside namespace std. I've seen a lot of people recommending "This is C++, you should be using <cxyz> instead of xyz.h". This advice is misleading; the two headers do not provide the same definitions, so inclusions of the C++ header cannot simply replace inclusion of the C header. Whether all the code should be rewritten to use the C++ qualified names instead is debatable... but is a prerequisite for changing the includes.
One thing that may help you is to list the headers actually used using gcc -M. Then you can decide whether any of the indirectly included headers should be listed in your code.
Standard headers can include each other. The headers you want to not include might be included by another header you use.
In this case you may want to manually #define the header guards of the headers you don't want before including anything, but that's a little dirty.
In my code base, I 'hide' implementation details of heavily templated code in .tcc files inside a bits sub-directory, i.e.
// file inc/foo.h:
#ifndef my_foo_h // include guard
#define my_foo_h
namespace my {
/* ... */ // templated code available for user
}
#include "bits/foo.tcc" // includes implementation details
namespace my {
/* ... */ // more templated code using details from foo.tcc
}
#endif
// file inc/bits/foo.tcc:
#ifndef my_foo_tcc // include guard
#define my_foo_tcc
#ifndef my_foo_h
# error foo.tcc must be #included from foo.h
#endif
namespace my { namespace details {
/* ... */ // defails needed in foo.h
} }
#endif
Of course, there must only be one file bits/foo.tcc in the include path. Otherwise, there will be a clash and (hopefully) a compilation error. This just happened to me with bits/vector.tcc, which is included from gcc's (4.8) vector but also my own header (using #include "bits/vector.tcc" and not #include <bits/vector.h>).
My question: is this formally a bug of gcc (since it uses a name bits/vector.tcc which is not protected by the standard) or correct, i.e. even formally my fault? If the latter, what names for header files are guaranteed to be okay to use?
(note I don't want to hear obvious advices of how to avoid this).
Edit The problem is that the header file vector provided by the standard library (shipped by the compiler) has a preprocessor directive #include <bits/vector.tcc> which causes the preprocessor to load my file rather than that provided with the standard library.
Here's what the C++11 standard [cpp.include] has to say about this:
1 A #include directive shall identify a header or source file that can be processed by the implementation.
2 A preprocessing directive of the form
# include < h-char-sequence> new-line
searches 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.
3 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.
In other words, #include < > is intended for searching for headers only. A header is one of the things provided by the standard library. I say "things" because the standard doesn't specify what it is - it doesn't have to a file at all (although all compilers I know implement headers as files).
#include " " is intended for "everything else" - in terms of the standard, they're all "source files," although in general speech we usually refer to files intended for being #included as "header files." Also note that if no such source file is found, a (standard library) header will be searched for instead.
So, in your case:
The standard doesn't say anything about files like bits/vector.tcc; in fact, it doesn't say anything about any files. All of this falls under the "implementation-defined" heading as is thus up to your compiler and its documentation.
At the same time (thanks to #JamesKanze for pointing this out in the comments), the standard clearly specifies what #include <vector> should do, and never mentions that it could depend on a file's presence or absence. So in this regard, gcc loading your bits/vector.tcc instead of its own is a gcc bug. If gcc loaded its own bits/vector.tcc instead of yours, it would be within its "implementation-defined" scope.
#include "vector" is primarily intended to include a source file named vector. However, if no such file is found, the effect is the same as including the standard header <vector> (which causes class template std::vector to be considered defined).
The standard is pretty open, but... including <vector> should
work; I don't see anything that authorizes it not to (provided
you've done #include <vector>, and not #include "vector"),
regardless of the names your personal includes.
More generally, the more or less universal algorithm for
searching for a header is to first search in the directory which
contains the file which does the include. This is done
precisely to avoid the type of problems you have encountered.
Not doing this (or not using some other mechanism to ensure that
includes from standard headers find the file they're supposed
to) is an error in the compiler. A serious one, IMHO. (Of
course, the compiler may document that certain options introduce
certain restrictions, or that you need to use certain options
for it to behave in a standard manner. I don't think that g++
documents -I as being incompatible with the standard headers,
but it does say that if you use -iquote, it shouldn't
influence anything included using <...>.)
EDIT:
The second paragraph above really only applies to the "..."
form of the include. #include <vector> should find the
standard header, even if you have a file vector in the same
directory as the file you are compiling.
In the absense of -I options, this works. Universally,
however, the -I option adds the directory in the search lists
for both types of include. The reason for this is that you,
as a developer, will probably want to treat various third party
libraries (e.g. X-Windows) as if they were part of the system as
well. (I think Linux does put X-Windows as part of the system,
putting its headers in /usr/include, but this wasn't the usual
case in other Unices in the past.) So you use -I to specify
them, as well as you're other include directories. And if you
have a file vector in one of your other directories, it will
"override" the system one.
This is clearly a flaw: if I recall correctly (but it's been
some time), g++ at one time did have additional options to put
a directory in the list for only one type of include. And in
modern gcc/g++, there's -iquote (and -I-, which specifies
that all of the earlier -I options are for the "..."
includes only). These features are little used, however,
because gcc/g++ is the only compiler which supported them.
Given all this, the gcc/g++ handling is probably the best you
can hope for. And the error isn't in the compiler itself, but
the library headers, which use <bits/vector.tcc> when it
absolutely wants the include file from the same directory as the
file doing the including. (Another way of saying this is that
bits/vector.tcc isn't a system header, in any sense of the
word, but an implementation header of system library.)
None of which helps the original poster much, unless he feels
like modifying the library headers for g++. (If portability
isn't any issue, and he's not considering his headers as part of
the system, he could change the -I to -iquote.)
Suppose i am editing some large C++ source file, and i add a few lines of code that happen to use auto_ptr, like in the following example.
#include <string>
// ... (much code here)
void do_stuff()
{
std::string str("hello world");
// ... (much code here too)
std::auto_ptr<int> dummy; // MY NEW CODE
// ...
}
This example compiles on gcc 3.4.4 (cygwin), because the standard header <string> happens to include the header <memory> needed for compilation of auto_ptr. However, this doesn't work on gcc 4.5.0 (mingw); they seem to have cleaned up their header files or something.
So, when i add code that uses auto_ptr, should i immediately go look whether the file contains #include <memory> at the beginning, as this answer implies? I never do it (i find it too annoying); i always rely on the compiler to check whether any #include is missing.
Is there any option that would not be disruptive to coding, and would ensure portability of my code?
Is there a C++ standard library implementation whose headers don't include each other more than is required?
If you use something in the standard library, you should include the header in which it is defined. That is the only portable option. That way you avoid the instance you cite where one header happens to include another in one version or compiler, but not another. auto_ptr is defined in <memory>, so if you use it, include that header.
[edit...]
In answer to your comment... Are you asking if the compiler can help detect when you use something from a standard header you didn't directly include? This would be helpful, but I think it's a little too much to ask. This would require the compiler to know which standard library headers contain which standard library definitions, and then check that you included the right ones for the definitions you used.
Determining exactly how a header was included is also a tall task. If you are using a standard library definition, then you must be including the header somehow. The compiler would have to tell whether you included the header yourself (possibly through headers of your own or a third-party library) or whether it came through another standard library header. (For instance, in your example, it would have to be able to tell the difference between <memory> being included via <string> or being included within your own code.)
It would have to handle different version of the standard library (e.g. C++03 vs C++0x) and different vendors. And what if those vendors of a third-party stdlib do not exactly follow the standard, then you could get bad warnings about which headers to include.
I'm only saying this to try to explain (with my limited compiler/stdlib knowledge) why I don't think compilers have this feature. I do agree, it would be helpful, but I think the cost outweighs the benefit.
The best way is to include the correct header in which the construct is defined.
and Include files should protect against multiple inclusion through the use of macros that "guard" the files
Generally header files have "include guards" surrounding them. The guards are formed by:
MyHeader.h:
#ifndef __MY_HEADER_H__
# define __MY_HEADER_H__
//body of MyHeader.h
#endif
So, you could include MyHeader.h as many times as you want:
#include "MyHeader.h"
#include "MyHeader.h"
#include "MyHeader.h"
#include "MyHeader.h"
And it won't cause any problems for the compiler (it will only ever be included once). Moreover you could include another file that includes "MyHeader.h", and the same rule would apply.
What this means is, if you ever want to use something that is defined in a header - include it! (Even if you think something else might include it, there is no reason not to be safe).
I had only just noticed my programs using the string class were compiling without including the <string> header. It turns out that <iostream> includes <ios_base> which in turn includes <string>.
Is this bad practice and should I explicitly include <string>? Even if it's just a case of clarity?
Is it safe to assume this applies to more than just the <string> header? Perhaps this is implementation specific and or does the standard state the <string> header be included via <ios_base> and <iostream>? Ensuring that any respected and widely used implementation will always include <string> providing the the call to <iostream> exists.
You should explicitly include whatever standard library headers you need.
It is not specified which standard library headers are included by other standard library headers, so such details will differ between compilers.
One case where you can rely on a header being included by another header is if a class in one header derives from a class in another. For example, <iostream> has to include <ios_base> because classes defined in <iostream> are derived from classes defined in <ios_base>.
A good practice is to always include the headers for the classes you'll be using in a given source file, regardless of whether you "know" they're included by already-included files.
If, while refactoring your code, you remove the necessity for one of the higher-level included files (iostream, for example), it could become quite painful to determine why your application no longer compiles.
If you add a proper header (with '#pragma once' or the proper #ifndef) more than once, it only adds a little more time to compiling (just to open, parse and through away the header file contents), but nothing too serious while it makes your files more easy to compile, should the circumstances change (i.e. move them to a different project, make a library out of them, e.t.c.)
If you are really concerned about compile time add the same #ifndef before including the header (though I don't recommend it)
i.e.
// header.h
#ifndef _HEADER_H
#define _HEADER_H
int blahblahblah(int);
#endif
// cppfile.cpp
#ifndef _HEADER_H
#include <header.h>
#endif