Why does count_if() work without algorithm header? - c++

Trying to brush up on my C++, I picked up a helper function I needed from a web search and tried it out before looking it up in the C++ reference:
int count_vowels(const std::string &input) {
return std::count_if(input.begin(), input.end(), is_vowel);
}
When I looked up more details on count_if(), I found that it's part of the <algorithm> library code (http://www.cplusplus.com/reference/algorithm/count_if/), which I had not included when I compiled and ran it. Why would the function work without the <algorithm> header? I have included <iostream>, <string> (obviously) and <sstream<>. And I'm using the compile flag -std=c++11 if that matters at all.
Also, if it works without the <algorithm> header, should I put that header in anyway for clarity's sake (or because other compilers wouldn't necessarily pick up the necessary function definition)?

It works because it's probably included indirectly via one of the other headers. It's not guaranteed though, and it might break on a different compiler, or a future version of the one you're using now.
Include all the headers you need directly.

If you are using Visual C++ then you can turn on show includes to see what files are included, via Project -> Settings -> C/C++ -> Advanced.
If using gcc then this explains the equivalent: /show include equivalent option in g++
You will then know where it is being included.

Related

visual studio does not give error if a header is missing

I am testing with a simple test program right now. It looks like below:
#include <iostream>
using namespace std;
int main() {
string s = "a b c d ";
remove(s.begin(),s.end(),' ');
}
When i build it with visual studio, it builds correctly and does not give any error. However if i try to build it with eclipse (mingw), it complains about the functions 'remove', as it should because the corresponding header is not included.
Is there a way to configure visual studio such that it will also complain and not auto-include headers or whatever fancy thing it is doing? I have already checked by disabling the option to use pre-compiled headers in visual studio project properties, and that doesn't help.
When you write a program that fails to include the proper headers, some toolchains may still just so happen to successfully build your program, because maybe their <iostream> happens to ultimately include the header you need (like <algorithm>).
That doesn't change the fact that your code is wrong. You're getting a build by chance.
You don't configure another toolchain to do that. You fix your code to include the correct headers.
So:
#include <string>
#include <algorithm>
The C++ Standard does not define, that a certain file needs to be included for the contained definitions to be able to be used.
It only defines in which files the specific functions are defined.
So if the specific implementation which You use includes everything through a file and You don't need to include anything else, than that is still allowed by the Standard.
So in one implementation, everything will compile, while in another errors will appear.
This is not controlled by the C++ Standard.
What You can do is file a bug to the implementors, and see if they agree that it's a bug. (In this case: https://github.com/microsoft/stl/issues)

'strtoll' and many others "not a member of 'std'"

strtoull,strtof,strtold,vsnprintf,wcstoll,wcstoull,wcstof, and wcstold are not members of 'std.' The problem is I don't use any of these functions. I didn't even know they existed. they are in file basic_string.h, which I also didn't know I was using. I'm using VS2015 so I assume I am compiling using the VSC++ 14.0 compiler.
I see that there over a dozen similar questions but I can only find two common errors: not using the C++11 flag and not #includeing . I have had the C++11 flag set and #include <algorithm> changes nothing. this question makes me curious,though. I thought the order of #includes didn't matter. I tried system libraries <> first and 3rd party libraries second "" and also vice-versa and observed no difference.
I also tried #include "stdafx.h" as some other answers indicated, but no such file exists.
not sure what to include here because I finally got to the point where the IDE identifies no errors in my code. again, all the issues are in "basic_string.h." here are my includes:
#include <iostrream>
#include <string>
#include <cstring>
#include <sstream>
#include <map>
#include "curl/curl.h"
#include "curl/easy.h"
this may be a continuation of my other question here, which I will update now.
edit 1: I have included <cstdlib>,<cstdio>,and<cwchar> and I see no difference. I'm curious why it's having issues with functions I've never used in files I've never touched.
I totally forgot I ran a repair on VS2015 yesterday and here are the results. I'm not sure if these are optional modules or core issues or what. "Windows Software Development Kit" sounds important but I am not developing for a windows machine(though I am developing on Win7).
edit 2: someone asked for minimal reproducible code. here is the whole file sans comments:
#include <iostream>
#include <string>
#include <cstring>
#include <cstdlib>
#include <sstream>
#include <map>
#include <cstdio>
#include <cwchar>
int main(int argc, char *argv[])
{
return 0;
}
just realized I don't need all the includes for nothing(because i commented all functional code out) so I will now see which one is causing the issue.
edit 3 : cstring,cstdlib,cstdio, cwchar, and the two curl headers are the only headers that will not cause this issue. I can include all six of them at once without issue. any other #include that was mentioned in the OP or the previous edit will cause the same ...is not a member of 'std'error. However, I don't think I had any of the <c...>included before I started having this issue.iostream,string,sstream,map each (individually even) cause this issue. are we still looking at a complete VS2015 reinstall?
edit 4: As one user suggested, I tried to make a new project but this is what happened. I was really hoping we wouldnt get to this point because I'm not sure how much you all will be able to help. Basically,we have some complicated build setup which I don't understand. The other guy who works here also does not understand the setup. The one person who knows is out on paternity leave. I'm developing on one machine and building/debugging on a server. However, I was poking around the settings and I saw a different diagram that has a second server in the mix and I'm not sure how that plays into it. After that, it is deployed to a different machine. Anyway I selected the same options as the current project but I can't even create a blank one. I'm not sure if this failure is because of this complicated system or because my VS2015 is messed up. Either way I can't fix this as it is so I think I will work on repairing VS2015 (which already had issues once) while monitoring this thread to see if this new project error reveals something important. thanks a lot to all who helped so far
edit 5: I'm taking next week off. I won't be able to give any updates till the 3rd for anybody who still cares. I'm going to repair and then reinstall
Those functions are in the namespace std if you include the correct standard headers, which are <cstdlib>, <cstdio> and <cwchar>. "basic_string.h" is not a standard header; it is probably some implementation specific header. "stdafx.h" is what Visual Studio uses for precompiled headers (it's not in the standard either) and the order in which you include headers can matter although it usually shouldn't.
I see that there over a dozen similar questions but I can only find... not #includeing
That appears to be the problem.
In order to use standard functions, the header which declares those functions must be included. The listed functions cannot be used because the corresponding headers haven't been included.
For example, strtoull is declared in <cstdlib>, which has't been included according to your quoted list of includes.
The problem is I don't use any of these functions. I didn't even know they existed. they are in file basic_string.h
If the error indicates that basic_string.h uses those functions, and that's the list of headers that basic_string.h includes, then basic_string.h is buggy.
I'm curious why it's having issues with functions I've never used in files I've never touched.
You either use basic_string.h, or you use some header that in trurn uses basic_string.h. The error message should tell you how the inclusion takes place.
I have ... #include <algorithm>
Including <algorithm> lets you use the declarations from that header. It doesn't let you use declarations from other headers.
I also tried #include "stdafx.h" as some other answers indicated, but no such file exists.
If your project is configured to use pre-compiled "stdafx.h", then you must include it. If it is not configured to use it, then you must not include it. Pre-compiled headers must be included before anything else in your file.
it was a problem with my Include directories in VisualGDB Properties-->Makefile settings. I was adding a new directory for each library I got. I reinstalled VS2015, but that did nothing because the culprit was a project option. I copied the default* include directories and that was it.
*someone on my team provided me with a list of the default include directories

Where is namespace std defined?

I want to take a peek inside of namespace std but, i'm not able to actually find the file on my computer where it is defined. I tried googling this but, i haven't had much luck.
On most Unix systems, the C++ headers are usually stored in /usr/include/c++/<version>/, where <version> is the GCC/libstdc++ version (i.e. 4.9 or 4.9.2), or else the libc++ version i.e. v1.
Within that directory are all (or just most?) of the standard-mandated headers, which are mostly just ordinary C++ code. For libstdc++, note in particular that most of the older headers just include something in bits/; few of the C++11-specific headers do this.
A list of every thing included in namespace std can be found here.
If you are using Visual Studio you can find it locally here :
~\Microsoft Visual Studio\VC\crt\src
There is also an online representation here.
NOTE : Edit the src files at your own risk, I'd recommend not editing them at all.
Many of the things implemented in the std namespace are templated, which means their entire implementation will be in the header files. For example, std::vector should be in the vector header file. Simply look at the options for your compiler to find out where those header files are located.
There may be some non-templated parent classes and free standing functions, which will not be in the headers. Again, look at the compiler documentation to see if the source files are included somewhere and where they would be.

Can C++ Headers be called vector.h or matrix.h?

I have including problems in a C++ Project. I included math.h, but there are strange problems with my vector.h and my matrix.h header files. Am I allowed to call these files vector.h and matrix.h?
Two headers cannot have the same name.
By same name, the full path name is implied, so
#inlcude "testClass.h"
#include "heders/testClass.h" // OK, distinguishable
Visual studio prevents you from adding a header having a name that already exists in the project.
You should also check that your header is actually included in your project (or through your Makefile, build system etc). A quick check would be to cause a syntactic error in that header and see if it breaks the build
So to get back to your question, do you already have headers called vector.h and matrix.h? Cause that would be the only thing preventing you from naming new headers like that.
Keep in mind that headers accessed with #include <...> require their folder to be set as an include (external) directory so qualifying up to that path won't work
In theory I don't know of anything to prohibit doing so.
I'd consider vector.h close enough to <vector> that using it would be a poor idea.
I'm not exactly excited about matrix.h either, but at least it's not nearly so obviously a poor choice.
Of course, for any header you wrote yourself (rather than one provided by the tools you're using) you want to enclose the name in quotes, not angle brackets.
The rationale why C++ chose the unusual <vector> format without suffix is because the intent was to remain compatbile with existing C code which might very well have "vector.h". So the answer is yes, by design.

Deciding which standard header files to #include

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