Why does VC++ compile the code while clang doesn't? - c++

I use VS 2015 (Update 3) to compile the following code:
#include <codecvt>
#include <cctype>
#include <functional>
int main()
{
std::function<int(int)> fn = std::isspace;
}
If I use VC++ to compile it, it's ok. However, if I change the compiler to Visual Studio 2015 - Clang with Microsoft CodeGen (v140_clang_c2) in Visual Studio, clang reports an error:
main.cpp(7,26): error : no viable conversion from '' to 'std::function'
std::function fn = std::isspace;
More surprising, if I comments the first line as follows, clang will also be ok.
//#include <codecvt> // now clang feels happy
#include <cctype>
#include <functional>
int main()
{
std::function<int(int)> fn = std::isspace;
}
What's the root cause?

std::isspace is overloaded in the standard library.
Due to the structure of their standard library headers, one compiler sees two different declarations of the name.
Then its use without arguments or casting is ambiguous.

std::isspace is ambiguous, it can either refer to the function found in <cctype> which is for compatibility with C, or the function template found in <locale>.
You can resolve the ambiguity with
std::function<int(int)> fn = static_cast<int(*)(int)>(std::isspace);
Or by omitting the std:: namespace, although technically there's no requirement for implementations to import the C functions into the global namespace.
The Clang and GCC implementations of <codecvt> both seem to include declarations of the template from <locale>, hence the error; presumably VS doesn't.

Related

namespace "std" has no member "clamp"

VS2015 wont compile my code, says namespace "std" has no member "clamp", although intellisense picks it up just fine and tells me the parameters and return value.
Yes, i have included the header.
#include <Math/Matrix3D.h>
#include <glm.hpp>
#include <gtx/transform.hpp>
#include <Utils/Clock.h>
#include <algorithm>
void somefunc()
{
viewPos.y = std::clamp(viewPos.y, -0.95f, 0.95f);
}
You would have to use the /std:c++latest switch to enable C++17 additions to the standard.
https://blogs.msdn.microsoft.com/vcblog/2016/06/07/standards-version-switches-in-the-compiler/

dynamic linker error with rand() function

I already asked a question about this before but with reference to the following code again
#include <iostream>
using std::cout;
using std::endl;
#include <dlfcn.h>
int rand() throw() {
// get the original rand() function
static auto original_rand = (decltype(&rand)) dlsym(RTLD_NEXT, "rand");
cout << "Call made to rand()" << endl;
return original_rand();
}
Why does compiling this result in the following error
error: exception specification in declaration does not match previous declaration
Why would this happen? How does the linker know that this is just another rand() function I have declared myself but rather an existing version of rand()?
One of your header files (<iostream> in my case) silently includes <stdlib.h>, which contains the rand() function. The latter does not have any exception specification. In your code you try to overload rand(), but the signature is the same as the one from <stdlib.h> except the exception specifier (which is not part of the function type, so cannot overload on it alone), hence you get a compile-time error (not a linker error, as you mentioned in the question).
If you wonder why the function rand() silently included is also visible in the global namespace (not visible only as std::rand as you may expect), that's because often the C library functions are imported into the standard C++ header files via a direct
// <new_cpp_header>
#include <old_c_header.h>
followed by
namespace std
{
using old_function_from_old_c_header;
}
so the function ends up in both global namespace as well as in namespace std;. This is not a very good practice IMO, but that's how most compilers do it nowadays.
For example, the <cstdio> file has:
// <cstdio>
#include <stdio.h>
namespace std
{
using printf;
// ...
}
so both printf and std::printf are visible, even though you include only <cstdio> (and not <stdio.h>).

Is there a method to use gmpxx.h together with c++98?

Because of my project I need to use c++98 and gmpxx.h:
But even for a simple project, it doesn't work:
#include <gmp.h>
#include <gmpxx.h>
int main()
{
int xrange=5,yrange=5,component=5;
return 0;
}
The error message is:
I tried using the following compiling methods
libc++: support c++11 and thus work
libstdc++: only support c++98 and do not work
Is there a way to use c++98 to implement gmpxx? thank you :)
Detail of errors when using c98++ to implement:
The breaking line is:
cout<<r<<endl;
But it works in c++11:
The error report:

c++ mingw STL installation

I recently installed MinGW and MSYS on my Windows 32 machine and it seems to be running fine.
On the C++ compiler, I am including a vector container and getting no errors to that. But I`m getting compile-time errors when I try to use it.
So, the code
#include <vector> // include vector.h
#include <stdio.h> // include stdio.h
using namespace std;
main() {
// vector<int> A;
printf("\nHeya ..");
}
is running just fine. However, the moment I un-comment line 8-- the vector declaration line, I get the following error (shortened) in compile time:
undefined reference to 'operator delete(void*)'
undefined reference to '__gxx_personality_v0'
You're probably compiling with gcc instead of g++. The actual compiler is the same, but g++ tells the linker to use the default C++ libraries, were gcc only tells it to look at the C libraries. As soon as you use and C++-specific parts of the standard library, gcc will fail.
As an aside, C++ doesn't support the default int rule from old C, so you should really specify the return type from main.
I don't see how you are compiling your code. Your main method is invalid, incorrect signature and you aren't returning anything.
Should be like this:
#include <vector> // include vector.h
#include <stdio.h> // include stdio.h
using namespace std;
int main(int, char**) {
// vector<int> A;
printf("\nHeya ..");
return 0;
}
Also you need to compile this with g++ and not gcc.

STL algorithm function name resolution

I'd expect in the example bellow compiler will fail to compile the code, since it
doesn't know what is "find()", which defined in std namespace in algorithm header.
However this code compiles on RHEL 5.3 with gcc 4.1.2.
What do I miss?
#include <string>
#include <algorithm>
int main()
{
std::string s;
find(s.begin(), s.end(), 'a'); // should not compile
}
This works due to Argument Dependent Lookup. The function-template is searched in the namespace of the arguments types. In this case, the arguments are std::string::iterator, so the function is searched in the namespace std.