I wrote a program that utilises INT_MIN. However, I did not include <climits> header file using the include directive. But my program still compiled without any errors or warnings. How? Did the compiler automatically include this header file?
Compiled the program using g++.
Edit: I only included the iostream library.
To have a less controversial example, consider this code:
#include <iostream>
int main() {
std::string s{"asd"};
std::cout << s;
}
It compiles without error here https://godbolt.org/z/fWbK4Yc5z.
If you use std::string you should include string. That does not imply that you can rely on an error when the include is missing. Standard library headers can include other headers. Here it happens that iostream apparently includes string. This is nothing to rely on. It may change with the next version of the compiler (I used gcc), and it can break on a different compiler.
The (inofficial) rule is: Include what you use. If you use std::string you should include string. If you use INT_MIN you should include climits.
Related
I use Dev C++ 5.11. TDM-GCC 4.8.1
And this code runs well.
#include<iostream>
using namespace std;
int main()
{
printf("%d\n", 42);
cout << "good";
}
But as far as I know, iostream does not include "printf". (http://en.cppreference.com/w/cpp/header/iostream)
Why this code run? iostream acutally include printf? Is it a kind of standard?
The list of header files included in a system/standard header file is library implementation dependent (that is usually associated with the compiler you're using), and (as far as I remember) the C++ standard does not prohibit one header file from automatically including another one
In your case <iostream> is probably also #including <stdio.h> (or <cstdio>).
Relying on a header file being included in another is non portable to different standard libraries, compilers and platforms, so it's better to make sure that you explicitly #include everything you need.
I am a beginner with C++. When I write the code sometimes I write #include <string> and the code works, other times I don't write #include <string> and the code doesn't work. But sometimes it works without #include <string>.
So do I have to write #include <string> so that the code works?
If you use members that are declared inside the standard header string then yes, you have to include that header either directly or indirectly (via other headers).
Some compilers on some platforms may on some time of the month compile even though you failed to include the header. This behaviour is unfortunate, unreliable and does not mean that you shouldn’t include the header.
The reason is simply that you have included other standard headers which also happen to include string. But as I said, this can in general not be relied on and it may also change very suddenly (when a new version of the compiler is installed, for instance).
Always include all necessary headers. Unfortunately, there does not appear to be a reliable online documentation on which headers need to be included. Consult a book, or the official C++ standard.
For instance, the following code compiles with my compiler (gcc 4.6):
#include <iostream>
int main() {
std::string str;
}
But if I remove the first line, it no longer compiles even though the iostream header should actually be unrelated.
It is possible that other headers that you do include have #include <string> in them.
Nonetheless, it is usually a good idea to #include <string> directly in your code even if not strictly necessary for a successful build, in case these "other" headers change - for example because of a different (or different version of) compiler / standard library implementation, platform or even just a build configuration.
(Of course, this discussion applies to any header, not just <string>.)
Although, there is no direct occurence of #include <string> in a particular source file, doesn't mean it hasn't been included by another header file. Consider this:
File: header.h
#if !defined(__HEADER_H__)
#define __HEADER_H__
// more here
#include <string>
// ...and here
#endif
File: source1.cc
#include <string>
void foo()
{
// No error here.
string s = "Foo";
}
File: source2.cc
#include <header.h>
void bar()
{
// Still no error, since there's a #include <string> in header.h
string s = "Bar";
}
File: source3.cc
void zoid()
{
// Here's the error; no such thing as "string", since non of the
// previous headers had been included.
string s = "Zoid";
}
If you're just using a pointer/reference to a user defined type, the type only needs to be declared:
class my_class;
void foo(const my_class& c);
But when you're using the value, the compiler needs to know the size and with that the definition of the type.
And keep in mind that standard headers may include other ones, which doesn't automaticly mean that all implementations do that, so you can't rely on that.
It is not true that the header string is included by other headers. The header string itself only has includes. No Definitions. So all necessary definitions needed for the usage of string are in headers included by the header string. These headers may already be included by other headers. Then everything works. The header ios for example includes stringbuf, which includes ...
Even though you haven't explicitly included string, it has been included because of another standard header you included. For example vector may have included string. When you include vector, every thing from vector will get included in your file.
I think future versions of Cpp should have a include_module or module keyword; which only include a specific module from a file. So if a file has 3 classes we only include the one we need.
for example
-I "../mingw/lib/include"
module <string>
Searches the directory for files that define string class. Compilation would be signicantly slower.
As Branko said:
It is possible that other headers that you do include have #include in them.
Let's take a look at iostream includes:
#include <bits/c++config.h>
#include <ostream>
#include <istream>
if you check istream you can see some include
so like this, we have:
iostream => istream => ios => iosfwd
and in iosfwd we have string library! but it's not standard, it's for forward declaration. in iosfwd we have:
#include <bits/stringfwd.h> // For string forward declarations.
and in stringfwd.h:
#file bits/stringfwd.h
This is an internal header file, included by other library headers.
Do not attempt to use it directly. #headername{string}
so, You can use string without #include <string>.
Why I don't need to include cstdlib and how do I disable this? I'm using Code::Blocks with GCC compiler on Windows 7.
#include <iostream>
using std::cout;
using std::endl;
int main()
{
cout << "Hello" << endl;
system("pause");
return 0;
}
You don't need to include <cstdlib> because it (or the part of it containing system()) was included by <iostream>. It is unspecified whether or which other (standard) headers are included by standard headers. You cannot disable this behavior but should be aware of it to avoid portability problems between different standard library implementations.
You should not depend on this behavior and include <cstdlib> yourself. You should also use std::system instead of the global system. Functions from <c*> headers are only guaranteed to be in the std namespace (the global ones, on the other hand, in the <*.h> headers).
I am using MS Visual Studio 2012 and in it, <iostream> includes <istream> which includes <ostream> which includes <ios> which includes <xlocnum>. <xlocnum> includes <cstdlib>, so your program indirectly includes <cstdlib>
Although the sequence of includes might be different in other compilers and/or implementations, the reason that this code runs is that <iostream>, either directly or indirectly includes <cstdlib>.
It should be noted the the libraries that iostream includes are implementation-specific and the code might not compile in some other compiler. As a general rule, the libraries that a header file includes are not usually well-documented or part of the standards, so do not rely on indirect includes. If you need a library, include it directly and, since standard libraries are include guarded, no significant overhead will be inflicted on your program's compilation or run-time.
I am a beginner with C++. When I write the code sometimes I write #include <string> and the code works, other times I don't write #include <string> and the code doesn't work. But sometimes it works without #include <string>.
So do I have to write #include <string> so that the code works?
If you use members that are declared inside the standard header string then yes, you have to include that header either directly or indirectly (via other headers).
Some compilers on some platforms may on some time of the month compile even though you failed to include the header. This behaviour is unfortunate, unreliable and does not mean that you shouldn’t include the header.
The reason is simply that you have included other standard headers which also happen to include string. But as I said, this can in general not be relied on and it may also change very suddenly (when a new version of the compiler is installed, for instance).
Always include all necessary headers. Unfortunately, there does not appear to be a reliable online documentation on which headers need to be included. Consult a book, or the official C++ standard.
For instance, the following code compiles with my compiler (gcc 4.6):
#include <iostream>
int main() {
std::string str;
}
But if I remove the first line, it no longer compiles even though the iostream header should actually be unrelated.
It is possible that other headers that you do include have #include <string> in them.
Nonetheless, it is usually a good idea to #include <string> directly in your code even if not strictly necessary for a successful build, in case these "other" headers change - for example because of a different (or different version of) compiler / standard library implementation, platform or even just a build configuration.
(Of course, this discussion applies to any header, not just <string>.)
Although, there is no direct occurence of #include <string> in a particular source file, doesn't mean it hasn't been included by another header file. Consider this:
File: header.h
#if !defined(__HEADER_H__)
#define __HEADER_H__
// more here
#include <string>
// ...and here
#endif
File: source1.cc
#include <string>
void foo()
{
// No error here.
string s = "Foo";
}
File: source2.cc
#include <header.h>
void bar()
{
// Still no error, since there's a #include <string> in header.h
string s = "Bar";
}
File: source3.cc
void zoid()
{
// Here's the error; no such thing as "string", since non of the
// previous headers had been included.
string s = "Zoid";
}
If you're just using a pointer/reference to a user defined type, the type only needs to be declared:
class my_class;
void foo(const my_class& c);
But when you're using the value, the compiler needs to know the size and with that the definition of the type.
And keep in mind that standard headers may include other ones, which doesn't automaticly mean that all implementations do that, so you can't rely on that.
It is not true that the header string is included by other headers. The header string itself only has includes. No Definitions. So all necessary definitions needed for the usage of string are in headers included by the header string. These headers may already be included by other headers. Then everything works. The header ios for example includes stringbuf, which includes ...
Even though you haven't explicitly included string, it has been included because of another standard header you included. For example vector may have included string. When you include vector, every thing from vector will get included in your file.
I think future versions of Cpp should have a include_module or module keyword; which only include a specific module from a file. So if a file has 3 classes we only include the one we need.
for example
-I "../mingw/lib/include"
module <string>
Searches the directory for files that define string class. Compilation would be signicantly slower.
As Branko said:
It is possible that other headers that you do include have #include in them.
Let's take a look at iostream includes:
#include <bits/c++config.h>
#include <ostream>
#include <istream>
if you check istream you can see some include
so like this, we have:
iostream => istream => ios => iosfwd
and in iosfwd we have string library! but it's not standard, it's for forward declaration. in iosfwd we have:
#include <bits/stringfwd.h> // For string forward declarations.
and in stringfwd.h:
#file bits/stringfwd.h
This is an internal header file, included by other library headers.
Do not attempt to use it directly. #headername{string}
so, You can use string without #include <string>.
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).