Consider the following code:
#include <iostream>
using namespace std;
int main () {
srand(time(0));
double dd [10];
for(int i=0;i!=10; ++i) dd[i]= rand()%5+0;
for(auto i:dd)
cout<<i<<' ';
cout<<endl;
exit(100);
}
Why is it compiling without the #include<ctime> and #include<cstdlib> for the calls to time(0) and exit(100)(which is absolutely useless there, I know)? Are they already included in iostream?
The C++ standard, section 17.6.5.2 [res.on.headers], says:
A C++ header may include other C++ headers.
Which means an implementation is free to include other headers when you include one of them. From an implementor's point of view, that's just quite practical, of course.
There are even headers which are guaranteed to include others. For example, <string> implies <initializer_list>.
As for <iostream>, it implies <ios> (which itself implies <iosfwd>), <streambuf>, <istream> and <ostream>. So there is no guarantee for <ctime> and <cstdlib>, and you should include them explicitly for better portability.
To find out which headers are guaranteed to include others, you can either have a look yourself in the standard or in a draft (see all the synopses starting in section 18), or just go to cppreference.com, for example http://en.cppreference.com/w/cpp/header/iostream for <iostream>. It's quite a reliable online C++ reference.
Or you just explicitly include every header you need. Which may be the best choice in the end.
Yes, iostream includes cstdlib (at least in your case; you should not rely on that dependency chain).
Your compiler might have an option to list the dependencies, e.g. for the GNU C compiler, you can use the -M flag to list all includes.
Related
I am reading from here : Can std::string be used without #include <string>?, <iostream> is calling <string>. But I do not see any includes of <string> in Standard library header <iostream> from c++ standard: https://en.cppreference.com/w/cpp/header/iostream. In <iostream> is only included <ios>, <streambuf>, <istream> and <ostream> according to that documentation. So this code works (file foo.cpp):
#include <iostream>
int main(){
std::cout << "enter srting\n";
std::string out; //std::string should not be included according to standard documentation
std::cin >> out;
std::cout << "test, " << out;
}
But I have to try to see dependecies generated from gcc:
cc -H foo.cpp |& vim -
and the output is (I have regex out files with string in it):
. /usr/include/c++/8/iostream
..... /usr/include/c++/8/bits/stringfwd.h
...... /usr/include/c++/8/string
....... /usr/include/c++/8/bits/basic_string.h
........ /usr/include/c++/8/ext/string_conversions.h
....... /usr/include/c++/8/bits/basic_string.tcc
So I can see that in the end, many "string" headers are indeed included
(so should I trust that documentation, when the did not mentioned <string> header in "Includes" list of <iostream>?).
Some of them are deeper on the #include stack (term from gcc manual), which brings me to question,
what calls what? And what is the "true" header, that define std::string of them? (is it /usr/include/c++/8/bits/basic_string.h?...)
from this question Why does omission of "#include <string>" only sometimes cause compilation failures?, they mentioned:
Some compilers on some platforms may on some time of the month compile even though you failed to include the header
But from the upper output of the "string headers", there is multiple of them , so how's possible for a compiler to compile only sometimes? Which of these headers are really important for successful compilation?
How to orient in cpp headers, which are meaningful for compiler, and could be tracked their "#include stack" (i.e. other meaningful headers)?
EDIT:
If it depends on my specific implementation of my stdlib++, then I want to know how can I determine from source whether that inclusion is made before I try to compile. Not by "If it compiles, then it works".
In general you cannot know what headers are transitively included by the headers you include, and any standard header is allowed to, but not required to, include any other header. And you shouldn't rely on transitive includes ever. You should include the headers you need for the things that you use and then you'll be good.
You should always check the documentation for any symbol you use and include any headers it is specified to require.
The C++ standard only specifies which symbols must be made available when a standard header is included. It does not place any limits on what other symbols are made available. In your example, the standard specifies the <iostream> must include <ios>, <streambuf>, <istream>, and <ostream>, but <iostream> may include any other headers its authors want. It may also forward-declare any symbols it may need.
(so should I trust that documentation, when the did not mentioned <string> header in "Includes" list of <iostream>?).
You should trust that the symbols specified as being available when you include <string> will be. That is all. You may not assume that those symbols will not be visible when including any other header.
what calls what? And what is the "true" header, that define std::string of them? (is it /usr/include/c++/8/bits/basic_string.h?...)
This is an implementation detail that can only be answered by inspecting the implementation's headers. Libstdc++ (the standard library implementation used by GCC) has the declaration of the std::string class in bit/stringfwd.h and its definition in bits/basic_string.h and bits/basic_string.tcc (for the current version, at least), but that is not required at all. If the libstdc++ maintainers decided they wanted to refactor and reorganize things, they would be free to do so. The only requirement that is guaranteed by the C++ language is that std::string must be available when <string> is included.
But from the upper output of the "string headers", there is multiple of them, so how's possible for a compiler to compile only sometimes?
Different standard library implementations or different versions of the same implementation could transitively include different headers. Different compiler flags (i.e. a debug flag or different standard compliance mode) could transitively include different headers.
Which of these headers are really important for successful compilation?
How to orient in cpp headers, which are meaningful for compiler, and could be tracked their "#include stack" (i.e. other meaningful headers)?
All of them are meaningful. The standard library's authors wouldn't include a header if they didn't need it for something. Just because you aren't using any symbols declared/defined in that header directly doesn't mean none are being used.
EDIT: If it depends on my specific implementation of my stdlib++, then I want to know how can I determine from source whether that inclusion is made before I try to compile. Not by "If it compiles, then it works".
The only way to know is to look at your standard library implementation's headers. There is nothing magical about them; they're just C++ code. If you want to know if <iostream> includes a declaration or definition of std::string, open your implementation's copy of <iostream> and look for a declaration or definition of std::string. Repeat this process for any headers that <iostream> includes.
<iostream> is calling <string>
Do you mean that it includes <string>? Calling is something that is done to functions.
But I do not see any includes of <string> in Standard library header <iostream> from c++ standard: https://en.cppreference.com/w/cpp/header/iostream.
What you're reading is documentation of <iostream>. Indeed, <iostream> is not documented to include <string>.
So this code works (file foo.cpp):
It may work with some standard library implementation. It may not work using other implementations.
(so should I trust that documentation, when the did not mentioned <string> header in "Includes" list of <iostream>?).
cppreference is fairly high quality. Unless it contradicts the standard, it is fairly safe to assume that it is correct. Indeed in this regard it is correct: <iostream> is not guaranteed to include <string>.
what calls what?
Some headers include some other headers. There is no need to know more accurately than that because you should not rely on transitive inclusions (except those that are documented).
And what is the "true" header, that define std::string of them?
As per documentation, std::string is defined in header named string (commonly stylised as <string> which matches the conventional inclusion syntax).
so how's possible for a compiler to compile only sometimes?
It could ask the current time from the operating system and use a branch to do one thing or another depending on that time. Compilers don't typically do that, but the point is that they could.
More realistically, you may at some point need to compile your program using another (version) of the compiler (or standard library implementation). Different implementations behave different from one another.
Which of these headers are really important for successful compilation?
The ones that are documented to define and declare the names whose definitions and declarations your program relies on. If you use std::string, then you must include the header that defines std::string which is <string>.
I am a newbie in c++, and I suspect, that, of course the question relates not only to tuple.
So, I've watched a tutorial with roughly this code:
#include <tuple>
std::tuple<...> t(...)
Why #include <tuple>? Especially, given the fact that we explicitly write std::tuple. The code compiles without that #include line just well...
Because <tuple> is a header file which contains the tuple class inside the namespace std. Just because you're explicitliy saying std:: doesn't mean the compiler will just be able to find it if it's not included.
The reason it worked for you in this case is probably because another header you have included already includes <tuple> and thus your code includes <tuple> indirectly or because the compiler you're building with includes it automatically. This is not guaranteed by the standard and should not be relied upon. Always include the headers you'll need to make your code portable.
You always should include the specific headers for any types that you use in your code.
The code compiles without that #include line just well...
That your code compiles without is just by chance, because it might have been included by another standard header you use in your program, and not guaranteed by the standard, and thus not portable.
Especially, given the fact that we explicitly write std::tuple.
The explicit use of the std:: namespace doesn't have any significance about that rule.
You should also always be explicit about using classes or types from the std namespace to prevent getting into ambiguity troubles.
Related stuff:
Why is “using namespace std;” considered bad practice?
Why should I not #include ?
How do I include the string header?
In C++ you need to include the header for everything you use. The std:: is about the namespace, it's completely different.
Apparently your compiler is smart enough to deal with it, but most of the compilers won't.
Some standard headers shall include other standard headers according to the C++ Standard. For example the header <algorithm> must include the header <initializer_list>.
However implementations are allowed to include standard headers in other standard headers at their discretion.
You should not rely on this because your program compiled with one compiler will not compile using another compiler.
Even if one standard header is included in another standard header according to the requirements of the C++ Standard nevertheless it is a good practice to include such a header explicitly because the user of the program (some other programmer) should bother about dependencies of the headers and will be free to include or exclude other headers.
I am working with Visual Studio 2017 Community Edition. It allows me to use both size_t and std::size_t without the appropriate includes. It appears to work with most of the std library. I assume it is because parts of the library itself use it. For instance one example that I found led to this behave was with vector.
#include <vector>
#include <iostream>
int main()
{
size_t a = 42;
std::size_t b = 0;
std::cout << a << b;
std::cin.ignore();
}
Presumably this is because the size() function returns an std::size_t. Is this just a header dependency and I can avoid it with the proper include? That still doesn't explain why I can call it with the namespace scope.
(I'm not using using namespace std.)
This question implies that not all headers in the std library should have the definition.
Strictly speaking your code is illegal. The size_t type is required to be declared in the following headers:
<cstddef>
<cstdio>
<cstdlib>
<cstring>
<ctime>
<cwchar>
But also the standard allows standard headers to include other standard headers. So most likely the header <vector> in the standard library used by MSVC includes one of the headers above. This is allowed, but not mandated by the standard so this will work on your setup, but can fail to work on other standard library implementations, even on a future version of the same one you are using.
So in conclusion try to include all the headers required by the standard for all the definitions you are using.
IMHO this is a faulty behavior, but is the required price C++ pays for backward compatibility to the inclusion system that seemed a reasonable design many years ago. The limitations and drawbacks of this are well known today and so the committee is working on modules, which is a modern alternative to the current inclusion mechanism.
As to why you can use size_t without std:::
<cstddef> is required to declare std::size_t and may also optionally declare (or bring in the declaration of) size_t in the global scope.
<stddef.h> is a C backward compatible header and it declares size_t at the global scope.
So either <cstddef> declares size_t at a global level and is included by <vector> or <stddef.h> is included by <vector> - most likely indirectly via <cstddef>.
https://stackoverflow.com/a/283023/2805305
This question already has answers here:
Removing '#include <algorithm>' doesn't break the code
(7 answers)
Closed 4 years ago.
#include <iostream>
using namespace std;
int main(int argc, const char * argv[]) {
int arrr[5] = {21,124,1521,123,1};
sort(arrr,arrr+5);
return 0;
}
As you can see above, I don't use #include <algorithm> but I can use the sort() function! Why? I don't know.
<iostream> doesn't have #include <algorithm>
Please tell me why this works.
I'm using Xcode on Mac OSX.
In C++, including any standard header is allowed (but certainly not required) to have the same effect as including any or all other standard headers.
In this case, it appears that some part of the implementation of <iostreams> used an algorithm from <algorithm>, so your inclusion of <iostreams> accidentally included <algorithm> as well.
Of course, you don't want to depend on this--on a different implementation, your code can (and often will) fail. Even updating your compiler (or possibly even just using different compiler flags) could prevent your code from compiling.
Whether standard headers include other headers is unspecified. It is not guaranteed that a standard header won't include any other standard headers. Standard (draft) quote:
[library] / [requirements] / [conforming]
/ [res.on.headers]
A C++ header may include other C++ headers. [snip]
So, std::sort happened to be declared, since it happened to have been included by <iostream>. But that was neither guaranteed by the standard, nor is it against the standard.
I'm learning C++ with the book C++ Primer, and it says that "size_t" is defined in "cstddef" header, but in this exercise:
#include <iostream>
using namespace std;
int main()
{
int ar[10];
for (size_t x = 0; x < 10; ++x)
ar[x] = x;
for (auto a : ar)
cout << ar[a] << " ";
cout << endl;
return 0;
}
That doesn't have included the header, Visual Studio 2017 (and c++ shell) compiles the program without error.
size_t is really a grey area. std::size_t is the result type of sizeof, but sizeof is a built-in operator you can use without any #include at all. Consider this complete little program:
// no includes, no using namespace std
int main()
{
auto x = sizeof(int); // x is std::size_t
}
On top of that, Visual C++ has always behaved a bit strangely here. Even with settings like /permissive- /std:c++latest in the newest version of the compiler, it still allows the following illegal code:
// no includes, no using namespace std
int main()
{
size_t i = 0;
}
In fact, it would even allow this:
// no includes, no using namespace std
int main()
{
int ar[10];
for (size_t x = 0; x < 10; ++x)
ar[x] = x;
for (auto a : ar)
;
return 0;
}
Nevertheless, what others said about the indirect inclusion of headers is correct. To be precise, the C++ standard says the following about standard-library headers at §20.5.5.2:
A C++ header may include other C++ headers.
Which means that Visual C++ behaves correctly in your case anyway. Once you include <iostream>, the implementation is free to indirectly include one of the six standard C++ headers that define std::size_t, and your using namespace std; (which is evil) does the rest.
The C++ standard even guarantees some of such indirect inclusions, but this isn't one of them, so in order to make your code compatible with other compilers, you are strongly encouraged to include <cstddef> or one of the others that guarantee std::size_t.
Standard headers are allowed to include other standard headers. Since headers in different implementations have different dependencies, you should still try to explicitly include everything that you need. It's possible that your program wouldn't build on Linux's libstdc++ or macOS's libc++, for instance.
Standard header will usually include other standard headers, so in many cases you might get away with not including proper ones.
The problem is that such relations between headers are not in the standard e.g. depend on implementatation. If you don't include required headers, your code might work on one compiler, but might fail on another.
Usually if you know that something defined in header X uses type T in its definition, you might assume type T will be available after including X. For example <vector> uses std::size_t as part of std::vector definition, so it will usually include <cstddef>.
Sometimes forward declarations can be used to avoid including other standard headers. But this is only possible with classes and structures, not typedefs.
Some implementations, like GNU Libc for example, are more strict and try to avoid including standard headers internally. Others, like MSVC, are less strict. Code that works with GNU Libc will usually work with MSVC.
It is hard to verify that your code includes everything you need. There are tools that can help you find missing include's, but building your code with multiple compilers is usually the best way to find those issues.
Nope, std::size_t might be defined in multiple headers:
Defined in header <cstddef>
Defined in header <cstdio>
Defined in header <cstdlib>
Defined in header <cstring>
Defined in header <ctime>
Defined in header <cwchar>
Also note, that <iostream> itself includes other headers.
Firstly, std::size_t is defined in a number of standard headers: <cstddef>, <cstdio>, <cstdlib>, <cstring>, <ctime>, and <cwchar>.
Without #includeing one of these, your code is not required to compile.
Practically, a lot of implementations of the standard library have various standard headers #include each other, in which case your code will compile. It is pretty common, but NOT guaranteed, for at least one of the headers that defines std::size_t (or even their C header equivalents like <stddef.h>) to be included by other headers in the C++ standard library.
More specifically, a lot of parts of the standard library work use dynamic memory allocation (standard containers, stream buffers, etc). An obvious - but not required - implementation choice is that they use size_t to represent sizes. For example, standard containers like std::vector have an associated size_type, and std::vector<any_type>::size_type can be, and often is, equivalent to std::size_t.
<iostream> (along with headers it automatically #includes) is not required to include a header that defines std::size_t, but - equally - nothing in the standard disallows it.
In the end it comes down to how cautious you want to be concerning portability. If <iostream> brings in a definition of std::size_t with your particular compiler, then your code will compile. It is possible (although unlikely in practice, not impossible) that a future release of your compiler will update the standard headers to change that. If you intend to port your code to another implementation (compiler and standard library) in future, there is a greater likelihood your code will need to be modified.
Practically, there is no harm by explicitly #includeing <cstddef> or any other header that defines std::size_t. That way, your code that uses std::size_t will compile, regardless of how other standard headers vary between implementations.