Why clang on Mac automatically includes some missing headers? - c++

I noticed that clang++ includes a missing header - <limits> on Mac, while g++ shows errors about it on Linux. Now I wonder why clang does it, and gcc not. And how I can force clang to not do it.
Here is a sample code which compiles by clang on Mac, but not by gcc on Linux:
#include <iostream>
using namespace std;
int main()
{
cout << "int max: " << numeric_limits<int>::max() << endl;
}
UPD
I looked into libraries and here is what I found.
Internally <iostream> includes <istream>, which defines >> operator for different types. <istream> wants to know limits for short, int and streamsize types.
clang++ uses libc++ standard library, which uses std::numeric_limits class template from <limits> in <istream> for this purpose. That's why this header is included automatically when <iostream> is included.
g++ uses libstdc++ standard library, which uses __gnu_cxx::__numeric_traits class template from <ext/numeric_traits.h> instead of using <limits> in <istream> (<bits/istream.tcc>). There is also a comment in that header which explains why they don't use <limits>:
<limits> is big and we avoid including it
Used compilers:
> clang++ --version
Apple LLVM version 8.0.0 (clang-800.0.42.1)
$ g++ --version
g++ (Debian 4.9.2-10) 4.9.2

In C++, unlike C, standard headers are allowed to #include other standard headers. That sometimes leads to mysterious errors like the ones you're seeing: one compiler's <iostream> includes <limits> and the other doesn't. The solution is to always include the headers needed for whatever names you use. In this case that means to #include <limits> in your code, even though it compiles okay as is with one compiler. There's no harm in #include a header that's already been pulled in, so that's okay with both compilers. It's annoying sometimes, but that's just the way things are.

The clang version of the <iostream> header likely #includes the <limits> header, as such you get it automatically as part of #includeing the <iostream> header.
There's nothing you can do about it. That's how that compiler's library is implemented. You can simply add
#include <limits>
to this file, and it should compile on both platforms.

Related

C++ Visual Studio warn about indirect includes

The following code compiles fine with Visual Studio 2013 (probably because <iostream> includes <limits>), but the "missing" #include <limits> prevents me as C++ newbie sometimes to understand whats going on. For example I realized that std::numeric_limits<int>::max() is in <limits> only after removing #include <iostream>.
So how can I force the compiler to require each include explicit?
#include <iostream>
int main() {
std::cout << std::numeric_limits<int>::max();
}
While this isn't a compiler "Warning" per say, you can have the MSVC compiler output a list of all included files at compile time with the /showIncludes flag MSDN compiler reference

Why g++ compiler is not able to find unique_ptr?

I am trying to compile a small C++ code which invloves unique_ptr as given below.
#include <iostream>
#include <memory>
using namespace std;
int main()
{
unique_ptr<int> p1(new int);
}
when I tried to compile the code using g++, it is throwing up 'unique_ptr' was not declared in this scope. I was trying to compile on Linux box. even I tried with '-std=c++11' option. It was saying 'unrecognized command line option -std=c++11'. Can any one please let me know how to fix this?
You need to include it, it comes out of the <memory> library
#include <memory>
According to the GCC 4.4 release notes, unique_ptr was not in GCC's standard C++ library before 4.4.
So you might want to check your GCC version first, using g++ --version like #40two said.

When I submit it online, they always says compile errors

That's my code:
It works good on my mac.
But I'm not sure is that the problem of Gcc version or not.
they said the sstream and string header are wrong.
1779655.134485/Main.c:8:19: fatal error: sstream: No such file or directory
compilation terminated.
here is the hint
#include <iostream>
#include <sstream>
#include <string>
using namespace std;
You are trying to include C++ header file in your C program.
Gcc is C compiler.
You need to rename Main.c to Main.cpp and use g++ compiler...

XCode upgraded to 4.4.1 and now I get errors compiling in stl <vector>

Upgraded to XCode 4.4.1 and restarted my machine, recompiled and now get the error below when I try to compile - any suggestions? (It used to compile fine)
(Running on Lion 10.7.4, XCode Version 4.4.1)
#ifndef MYFILE_H
#define MYFILE_H
#include <vector> <-- this line
#include <typeinfo>
#include <string>
#include "assert.h"
using namespace std;
Error message
In file included from /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator5.1.sdk/usr/include/c++/4.2.1/vector:69:
/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator5.1.sdk/usr/include/c++/4.2.1/bits/stl_vector.h:69:1: error: expected member name or ';' after declaration specifiers
_GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD)
If this problem is still actual, I suggest you should check the following project setup lines:
C++ Language Dialect (mine: Compiler Default)
C++ Standard Library (mine: Compiler Default)
Compiler for C/C++/Objective-C (mine: Apple LLVM compiler 4.1)
Not all combinations work and not always the "Compiler Default" is the default. I had some problems, too.
(From the error message it looks for me like you are using libstdc++ instead of libc++ but not the gcc compiler or so. I had similar problem after the update.)

program does not compile with newer version of g++

I have the following source code. Which compiles fine in visual studios and g++ 3.4.6; but not with g++ 4.4.3 (on a newer ubuntu machine). The newer compiler requires that I explicitly include to use atoi. I am just trying to figure out what might have changed to cause this behavior. Is it sstream header file previously included cstdlib and no longer does so. Or is it the compiler behavior that has changed.
#include <sstream>
int main()
{
char str1[]="123";
int i = atoi(str1);
printf ("value = %d",i);
return 0;
}
You also need to include <cstdio> for printf().
Technically, if you include the headers of the form <cname> instead of <name.h>, you also need to qualify the names from the standard library using std::. A lot of standard library implementations are relaxed when it comes to this, though, and also put the names into the global namespace.
It's implementation-dependent which headers are included by which other headers, so you should always be sure to include all the headers that you need and not assume that they will be included automatically.
I'm using GCC 4.4.5 on Debian, and the headers have changed so you will not bring in the headers necessary. You need to #include <cstdlib> and #include <cstdio> to get atoi and printf, as the compiler complained about both being missing.
#include <sstream>
#include <cstdio>
#include <cstdlib>
int main()
{
char str1[]="123";
int i = std::atoi(str1);
std::printf ("value = %d",i);
return 0;
}
Well yes. That is common. You should always include ALL headers that you are directly using and not depend on the fact that those headers are already included.
Compiler behavior is what would have changed... the <sstream> doesn't use atoi.
Arguably you should have always done #include <cstdlib>, and you'd gotten lucky with your previous compilers.
As James McNeillis points out, you should also #include <cstdio> in order to use the printf function.