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)
Related
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.
In our company sometimes we write .cpp and .h files, which are used in projects for old WM (we use Embedded Visual C++ 3.0 or something for this) and in more modern code (VS 2010).
This Embedded Visual C++ does not support STL.
So if one of developers, who works in VS2010, changes a file, which is shared, and adds some function, which uses std::vector, for instance, on his side everything will be OK, but the build (which is quite long) will fail.
So to see this mistake sooner, I would like to add something like
#if defined(%%STL%%)
#error("!!!!")
#endif
in all files, which are compiled with old toolset. In this case the developer could see compile time error even in VS2010.
But I could not find what I can put instead %%STL%% there.
Any ideas? Or maybe someone knows a better way how I can do this?
Based on a comment to the question, you could go through each of the header files that aren't supported and see what symbols they define for their include guard. Then check for those symbols being defined.
E.G. The Microsoft C++ header <algorithm> defines _ALGORITHM_ so you can check for that:
#ifdef _ALGORITHM_
#error("<algorithm> included")
#endif
A bunch of these could be collected up and put into a single header file that you could include in each shared source file, at the end.
There is quite a nice solution (at least I do not see pitfalls)
%%STL%% should be _STD_BEGIN
this macro is used for "namespace std {" in VS stl implementation
I just wrote a simple C++ program in Visual Studio 2010 and I use ceil function. But I forgot to include the <cmath> and only included the <iostream>. Surprisingly my code compiled successfully and ran without any error. I read a C++ book and it clearly says that to use ceil function you must include <cmath> or <math.h>. Why this happens? Can anyone explain me? Thanks!
The header is indirectly included from some other (indirectly) included header.
To find out which one, enable 'keep preprocessed source' (/P) from the project options and inspect the resulting (*.i) file
Update Just found out that VS2010 has renamed the related option:
Technically speaking, implementations are allowed to automatically include any header in the system headers. But this is implementation defined.
In some cases, <cmath> is already included, in other cases, it isn't - same applies to all the other standard headers.
This issue came up on this question: https://stackoverflow.com/questions/7632926/is-this-a-c-program-or-c-program-how-to-decide
That aside, it's possible that it could be indirectly included by other includes.
I'm working under Visual Studio 2008, maybe that's important.
In a larger project I decided to split one of my .cpp files into two. As I moved some of the functions to a new file, let's call it new.cpp, and tried to compile, I got errors that new.cpp doesn't know definitions of fstreams, setw(), etc. Now, at the very top of the new file I included my own header, let's call it main_header.h, which in turn includes all the necessary <iostream>, <iomanip>, etc. This works just fine all throughout older files used in this project, but for some reason doesn't in new.cpp.
If I add
#include <fstream>
#include <iomanip>
// and all the rest
in new.cpp then all works just fine, but that's not how I want to solve it.
I thought maybe content of main_header.h doesn't get appended to new.cpp on compilation, but that's not true, I tried using in new.cpp an external variable declared in main_header.h and defined in yet different .cpp, and got no errors on compilation, linking, or running. Yet it seems like <fstream> and <iomanip> included in main_header.h do not make it to new.cpp file.
I'm relatively new to Visual Studio, so the solution to my problem is likely something silly I'm not aware of, but I spent a good while trying to figure this one out and to no avail. The new file is definitely part of the project, since building projects attempts to compile it, plus once I include iostream and iomanip in this new.cpp I can call its routines in other parts of the project. Any ideas what I might be doing wrong?
main_header.h looks like that
#ifndef MAIN_HEADER
#define MAIN_HEADER
#include <iomanip>
#include <fstream>
// loads of other stuff
#endif // for MAIN_HEADER
Update: Ok, so the day after I created a whole new project using the same files and now all works fine, I don't need to include iomanip nor anything else in new.cpp. It sure as heck was to do with some oddities of VS not code itself, but still beats me what exactly was the issue.
This could be caused by prefix headers or precompiled headers, which can be set across the whole project, or could be set just on your new.cpp file, which might explain why there's some difference. Here's a few things to try:
Properties -> C++ -> Precompiled headers: check the setting for the whole project and for the individual files
Properties -> C++ -> Advanced -> Force includes: check this is the same for both
Open the vcproj file in a text editor and find the new.cpp node -- this is a quick way of finding if this individual file has different compiler settings
Properties -> C++ -> Preprocessor -> Generate Preprocessed file: this will generate an intermediate new.i file with all #includes and macros resolved. Compare the result of this for both files and look for the diffs -- this might show why one works and the other doesn't
Do you have another header somewhere that also has #define MAIN_HEADER?
It's an easy mistake to make when creating a new header by copying an old one, and leads to mysterious symptoms like this.
So,
I've got this code I'm trying to update. It was written for visual studio 6, and I'm trying to get it to compile in visual studio 2010.
In stdafx.h, it includes afx.h and afxwin.h and a few other things necessary for the program to work. Notably, there's usage of CString in other header files.
At the top of the includes in stdafx.h, I added in a #pragma message, to verify that it was being compiled first. There's one at the top of the header file which throws the error, as well. I can see from the compiler output that stdafx.h was being compiled first, so that's good.
However, there was the error. (CString wasn't being recognized as a type.) So, I decided to make sure that it got through all of the includes. So, I put another #pragma message after #include and that message is not printed.
Does that mean is not actually being included?
Your explanation is a little hard to follow, but I think you're running into the differences between normal compilation and pre-compiled headers.
With pre-compiled headers, the compiler processes the first file normally (the new project wizard sets up stdafx.cpp for this). After processing the include file (typically stdafx.h) set in project options for pre-compilation control, the compiler saves its state to a .pch file.
For every other file, the compiler skims over the file without any processing, just looking for the include file. Then it reads the .pch file, loads the saved state, and continues parsing and compiling normally.
One consequence of this design is that any lines above #include "stdafx.h" in stdafx.cpp become part of the state and are seen by all other files. And lines above #include "stdafx.h" in other files are simply ignored.
Passing my comment to an answer.
CString in VS 6 times was a class and it changed afterwards to be a template. Maybe it has something to due with that?
The problem had to do with using
typedef with CString. Post VS 6,
that's not possible. I just changed
references by hand, and it compiles
now.
The problem had to do with using typedef with CString. Post VS 6, that's not possible. I just changed references by hand, and it compiles now.