Is string header file needed anymore? [duplicate] - c++

This question already has answers here:
C++ code compiles without include
(2 answers)
Why does omission of "#include <string>" only sometimes cause compilation failures?
(7 answers)
Closed 3 years ago.
So I am learning C++ at the moment, and at some point I saw that you "have to" #include <string> at the top of your code to use strings.But when I run my code, it does the same thing in both cases.So is it really needed to use it?
#include <iostream>
using namespace std;
int main()
{
string fullName;
cout << "Type your full name: ";
getline(cin, fullName);
cout << "Your name is: " << fullName;
}

Some compiler implementations include the header <string> in the header <iostream>.
But you shall not rely on this.

A compiler is not required to accept your program if you don't.
It might (coincidentally) be included through a different header and work anyway, but that might not be the case after your next compiler update or if you move to different platform.
Whether you "have to" include it is mostly down to how strict an environment you're working in – if you're hacking away at home you can do whatever, but if you're working for somebody else you're usually expected to Do The Right Thing.

Don't rely on transitive includes. Your implementation may include whatever it wants in other headers that may cause your code to work, but you cannot rely on that. A good, portable, robust program includes what it needs, when it needs it, explicitly. That way it stays working when you change compiler, standard library, Operating System, etc.

In C++, #include just says to paste the code from the file included into that location. If something is already #includeing string, then the compiler won't care if anything after it includes it.
This does not mean you should do that! Always include what you need. Don't rely on other headers, especially those from libraries, including anything for you.

Related

How can I determine what header calls another header in c++?

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>.

Protecting certain include locations

I'm building a little language that will compile to C or C++, I haven't decided yet, however I have come across a dilemma concerning the #include keyword.
My language will come with a standard library that will be incorporated into the language, and be accessible much like that of C or C++ with the standard includes such as #include <string>.
My compiler can automatically tell the difference between user includes and standard library includes, but my issue lies in how the GCC compiler uses the -I flag.
Let's take Java as an example. One of the default packages (folder) is called java.util. If I try to make my own folder called java.util inside my project, I get the error:
The package java.util conflicts with a package accessible from another module: java.base
Meaning it is included by default.
I would like this to do the same thing in C++, but am worried that a user could (hypothetically) do a relative path include and cause a conflict.
Take for example, I use the flag like so: -I ../some/folder.
However then the user could simply type #include "../some/folder" to access the same content. Is there any way I can restrict this, and like the title of the question suggests, "protect" the folder from being called like that?
Furthermore, if there is a file inside of that folder called test.h and the user decides to create their own file called test.h locally and include it. How will the conflicts occur? Will it pick the local folder over the included via. flags?
An example of a basic implementation is as follows: (General syntax, no specific language)
boolean userDefine = false;
string defineName = "foo";
// Do something to determine if <> define or "" define.
if (userDefine) {
// Returns #include "foo"
return "#include \"" + defineName + "\"";
} else {
// Returns #include "stdlib/foo"
return "#include \"stdlib/" + defineName + "\"";
}
But then again, the user could include the folder so that it satisfies the first condition and still gain access.
It's pretty much the standard practice to put any #include files at the very beginning of the C++ source file, as the first order of business.
Of course, a #include can appear anywhere in the C++ source file, and there are situations when that happens but, if you were to grab some random C++ source from github, chances are pretty good that all the #include files will be at the beginning of the file.
So, all you have to do, is to make arrangements that your library's #include is always at the beginning, and use the standard #ifndef/#define guards in your header files. Then, manual inclusion of them subsequently will have no effect whatsoever, no matter what path is used.
Of course, this won't stop anyone from manually #undefing your guard, to create some chaos. However, C++ never had a reputation for reliably preventing you from shooting yourself in the foot, and is unlikely to earn that reputation in the foreseeable future; so what? Actually, most compilers implement #pragma once, which might be a slightly better foot self-shooting prevention approach...

Can std::string be used without #include <string>? [duplicate]

This question already has answers here:
Why does omission of "#include <string>" only sometimes cause compilation failures?
(7 answers)
Closed 7 years ago.
Here is my code:
#include <iostream>
int main(int argc, char const *argv[])
{
std::string s = "hello";
std::cout << s.size() << std::endl;
return 0;
}
To my surprise, I can compile and run it with clang++, though I even don't add #include <string>.
So, is it necessary to add #include <string> in order to use std::string ?
Your implementation's iostream header includes string. This is not something which you can or should rely on. If you want to use std::string, you should always #include <string>, otherwise your program might not run on different implementations, or even in later versions of your current one.
In short: yes, it is necessary.
Parts of standard library often use other parts, so <string> was included somehow through <iostream>, and your code compiles nicely.
If you accidentally decide that you don't need <iostream> anymore and remove that include, <string> will be implicitly removed, too, and you get a confusing compilation error. That's why it is a good practice to put all necessary includes.
Some header might include other headers, but that's an implementation issue and not something you can count on. Always explicitly include the headers you need.
iostream includes <string>. It ripples through.
Well actually that's implementation dependant and not a guarantee. You should explicitly include the headers you need.

Why do you need to use include when you have declared a using? [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 7 years ago.
Improve this question
I'm learning C++ and I got stuck on why this happends. This code will compile and run perfectly, however if I uncomment the //cout << foo << endl; it won't compile.
#include <iostream>
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
{
string foo = "temporary";
//cout << foo << endl;
// Pause then exit
system("pause");
return 0;
}
I solved it by adding: #include <string>. Can anybody tell me why this is becuase to me (coming from C#) this doesn't make sense why you are allowed to create a string object but not printing it?
Thanks!
When you #include <iostream>, it's up to the header to include whatever other headers and consequence declarations and definitions it wants - the C++ Standard doesn't forbid it including more than is strictly necessary to provide the required functionality. Clearly, with your compiler/version, #include <iostream> is also including enough of the string related definitions to know there's a template <...> std::basic_string::basic_string(const char*); constructor (std::string is a typedef to a specific instantiation of basic_string for char) such that your code is known valid:
string foo = "temporary";
Still, when you went to stream foo, it clearly hadn't seen a matching definition ala template <...> std::ostream& operator<<(std::ostream&, const basic_string<...>&) that specifies how streaming is to be performed: that's why the compiler complained. The definition for operator<< is probably in your <string> header, which is why it really is needed before streaming a string.
You can observe this yourself by asking your compiler to output and not delete preprocessed files, which show the translation unit after #includes have been expanded. You'll find the options to do so somewhere in your project's build configuration.
All up, that's why you might sometimes have code work with fewer includes than are strictly necessary. If you realise you've done this, it's always a good idea to include the other headers, ensuring portability to other compilers and future versions of the same compiler.
The standard library documents per § 21.3 [string.classes] that using the string classes, their members, operator overloads, etc, requires inclusion of <string>. Any reliance that a different header does so, either of your own devices or some other header to include said-same, is non-standard compliant unless documented it does so (includes <string>). The insertion operator you're using is described in § 21.4.8.9 [string.io], but ultimately the same rules apply: include <string>.
You can speculate what may be allowing compilation to succeed without including <string> by avoiding using that inserter overload. Perhaps the operator overloads for std::basic_string are included in a manner that is not fulfilled by simply including <iostream> on your implementation.
That speculation makes little difference in the end, however. That is all it would be: speculation. Ultimately you're code is not well-formed because you're not following the rules per the standard, which thankfully in this case is trivially addressable.

C++ I/O library

I tried googling this but I get different answers at different places. I want to know the cases wherein one should use one of the following:
#include <stdio>
#include <cstdio>
#include <iostream>
I cannot figure out the difference since in my case all my C++ programs seem to work if I use these interchangeably. That being said, iostream seems to support the stream of input and output by defining cin and cout etc. However, I maybe wrong. I would appreciate answers / credible citations for the usage of these with reference to the C++ standards. I wonder if there are any performance benefits involved in using one over the other.
Nonstandard Headers
<stdio> is not defined in any of the standards that I know of.
Standardized Headers for C
<stdio.h> is the c header containing functions like printf() and scanf().
Standardized Headers for C++
<stdio.h> is included in the c++ standard but is deprecated.
<cstdio> is the c++ header that includes things like printf() and scanf().
<iostream> is a c++ header that include things like std::cout, std::cerr and std::cin.
stdio is for standard IO in C. It should have a .h at the end. In C++, all C headers have been encapsulated in cxxxxxx headers (without .h). So, <stdio.h> is the same as <cstudio>. These offer functions, like printf and scanf, for simple IO.
iostream on the other hand is an IO library for C++, and offers streams like cin and cout, as you mentioned.
Depending on your application you can use them interchangeably for most of the time. The syntax is going to be different, obviously.
Formatting text can be easier using the C functions. For example:
printf("item %04d has a value of %+.6e\n", index, value);
is easier to write than (needs <iomanip> in addition to <iostream>):
std::cout << "item " << std::setw(4) << std::setfill('0') << index
<< "has a value of " << std::setprecision(6) << value << "\n";
However, you need to be more careful when using the first one. For example, the following line won't produce a compile error (but as sharth mentioned, you might get warnings when compiling) but will cause runtime issues:
printf("I wonder what will happen? %d\n");
I don't think there is a lot of difference in their performance as most of the stream "magic" happens in compile time, and they should produce similar results. I'm not 100% sure though, so correct me if I'm wrong.
there is no stdio (stdio.h and cstdio). the 'c' and the missing '.h' in the header name indicates that it's the C++ version of the C header.
check cstdio and iostream (references)
some compilers (including MSVC) include stl headers in other stl headers which leads to the effect you observed. this is not portable though!
if you are concerned with performance: use the C++ variants and check this