In Visual Studio 2017 when creating Linux project and inserting using namespace std; in source code like this:
#include <iostream>
#include <string>
using namespace std;
int main()
{
size_t i = 1;
string s = to_string(i);
cout << i << s << endl;
return 0;
}
VS underlines size_t and says that it is an ambiguous symbol.
If I press F12 (Go to definition) it offers me two definition places:
From stddef.h
(C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\Linux\include\usr\include\x86_64-linux-gnu\5\include\stddef.h):
// ...
namespace std
{
typedef __SIZE_TYPE__ size_t;
// ...
And c++config.h
(C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\Linux\include\usr\include\x86_64-linux-gnu\c++\5\bits\c++config.h):
// ...
#if !(defined (__GNUG__) && defined (size_t))
typedef __SIZE_TYPE__ size_t;
// ...
It happens only with Linux projects in VS, not with Windows projects.
Is there any known solution (except for "do not use using namespace std; :) )?
Upd: Reported this problem to Microsoft: https://developercommunity.visualstudio.com/content/problem/67405/ambiguous-symbol-size-t-in-linux-projects-when-usi.html
Upd2: Microsoft says that they fixed it, and solution will be in next update: https://developercommunity.visualstudio.com/content/problem/67405/ambiguous-symbol-size-t-in-linux-projects-when-usi.html
It looks like there is a difference between Microsoft's and other compilers related to typedef in and out of a namespace.
This source file
namespace foo { typedef int moo; }
typedef int moo;
using namespace foo;
extern moo a;
compiles in g++ and clang++ (no warnings with -Weverything). MSVC rejects it because of an ambiguous symbol.
This is exactly the situation with size_t in gcc headers. It is typedefed both in and out of namespace std. This doesn't seem to cause any problems with
g++.
Why does this compile in g++ and not in msvc? I guess this is because of different interpretation of 7.1.3/3
In a given non-class scope, a typedef specifier can be used to redefine the name of any type declared in that scope to refer to the type to which it already refers.
Admittedly the interpretation by g++ is rather loose. The first moo is not declared within namespace :: so the rule seemingly doesn't apply. I cannot find anything else that would permit such a thing.
To solve the problem, I would patch the header where size_t is defined in the global namespace, and bring the declaration inside namespace std (conditionally, if __cplusplus is defined). But I have not tested it (no VC2017 here) and cannot guarantee it will work.
I also have no idea why your code is accepted by the actual compiler and only rejected by IntelliSense. I have tested this construction with actual compilers. (update to the last sentence: I have had the code tested with, and rejected by, MSVC. I have conducted the tests before realising that "the actual compiler" above is in fact gcc and not MSVC).
Related
i am doing the Vulkan Tutorial
https://vulkan-tutorial.com/
#define GLFW_INCLUE_VULKAN
#include<GLFW/glfw3.h>
#include<optional>
struct s {
std::optional<uint32_t> num;//Intellisense Error
};
int main() {
return 5;
}
I started with an empty project and added includes and libraries;
I can compile and run without including std::optional.
When i use std::optional I get c2039 "optional is not a member of std"
I am running Windows 10, and VisualStudio 2019
What is going on here ?
thx.
std::optional requires C++17.
Live on Godbolt.
you can use /std:c++17 flag on MSVC and -std=c++17 on gcc/clang.
I have a C++ code that uses endl, vector, complex, and cout occasionally without any namespace qualification. When compiling with GCC 4.9, I get errors like this one:
bfm.h:454:4: error: 'complex' does not name a type
complex<double> inner(Fermion_t x,Fermion_t y);
^
In the very same file, there are lines with an std:: qualifier:
std::complex<Float> dot(Fermion_t x_t, Fermion_t y_t,int sx,int sy);
Throughout the codebase, I saw the following template specializations used
std::complex<double>
std::complex<cFloat>
complex<Float>
complex<double>
complex<T>
complex<S>.
Neither for the regular express struct\s+complex nor class\s+complex I managed to find something in the codebase or the codebase of the base library. Therefore I assume that it indeed is the standard library complex type.
There are a couple of using namespace std scattered around in various header files, but not all of them.
I tried compiling this codebase with GCC 4.9 and Clang 3.7. Both give similar errors about the missing type. Is there some possibility that this has worked with an older version of GCC? I have tried to insert std:: at all the needed points but I have the impression that I do something wrong if I cannot just compile the source checkout that is meant for this type of computer.
you can use selective using... declarations or type aliasing to bring in only the std:: members you need. Like:
using std::complex;
using std::cout;
using std::endl;
cout << "Hello world" << endl; // works
complex<float> x; // works
fstream y; // compile error, no namespace qualification, no using declaration
std::fstream z; // OK
Ah, yes, maybe not that evident, so perhaps worth mentioning. You now that std::endl? Well, it's a stream manipulator, a function in fact.
Which means one can bring in the current block function members from other namespaces as well.
Like:
#include <cmath>
#include <cstdlib>
inline void dummy(float x) {
float y=fabs(x); // Na'a.., fabs is imported into std namespace by <cmath>
using std::itoa; // same is itoa, but we'll be using it
char buff[128];
itoa(42, buff, 10); // OK
}
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.
I want to use "Dev-C++" for compile c++ codes.
So I download and install it, and write this code:
#include <iostream.h>
main () {
cout << "124";
}
but when I compiled it, it said:
In file included from
E:/Dev-Cpp/include/c++/3.4.2/backward/iostream.h:31,
from [myfile path]\Untitled1.cpp:1:
E:/Dev-Cpp/include/c++/3.4.2/backward/backward_warning.h:32:2:
warning: #warning This file includes
at least one deprecated or antiquated
header. Please consider using one of
the 32 headers found in section
17.4.1.2 of the C++ standard. Examples include substituting the header
for the header for C++ includes,
or instead of the
deprecated header . To
disable this warning use
-Wno-deprecated.
After I saw errors, I change my code to this code:
#include <iostream>
main () {
cout << "124";
}
but it said again that errors.
I compile first code easily in Turbo C++, BUT in Dev-C++ ...
What can I do?
First, make sure you write out the full definition of main, including the int return type. Leaving out the return type is an old, antiquated practice which doesn't fly these days.
Second, in the new-style headers—the ones missing the .h extension—the standard library is under the std namespace. There are two ways to make your program work:
1. Add an std:: qualifier to cout.
#include <iostream>
int main () {
std::cout << "124";
}
2. Add a using declaration to allow unqualified references to the std namespace.
#include <iostream>
using namespace std;
int main () {
cout << "124";
}
Make sure you put int in front of main () {
I believe any C/C++ program's main() function is required by POSIX and the appropriate language standards to return an int (someone correct me if I'm wrong).
EDIT: Also, be sure to include using namespace std; above int main ().
I am new to C++ programming.
So I was trying my luck executing some small programs.
I am working on HP-UX which has a compiler whose
executable is named aCC.
I am trying to execute a small program
#include <iostream.h>
using namespace std;
class myclass {
public:
int i, j, k;
};
int main()
{
myclass a, b;
a.i = 100;
a.j = 4;
a.k = a.i * a.j;
b.k = 12;
cout << a.k << " " << b.k;
return 0;
}
When I compile this it gives me an error:
> aCC temp.cpp
Error 697: "temp.cpp", line 2 # Only namespace names are valid here.
using namespace std;
^^^
What exactly is the problem?
Is std not considered as a namespace in the aCC compiler or is there some serious drawback with aCC?
If I change the <iostream.h> to <iostream>, I get some more errors added as below.
>aCC temp.cpp
Error 112: "temp.cpp", line 1 # Include file <iostream> not found.
#include <iostream>
^^^^^^^^^^
Error 697: "temp.cpp", line 2 # Only namespace names are valid here.
using namespace std;
^^^
Error 172: "temp.cpp", line 14 # Undeclared variable 'cout'.
cout << a.k << " " << b.k;
Which version of aCC are you using? Older versions used a pre-standard STL implemenntation that put everything in the global namespace (i.e. didn't use the std namespace)
You might also need to use the -AA option when compiling. This tells the compiler to use the newer 2.x version of HP's STL library.
>aCC -AA temp.cpp
And it should always be
<iostream>
<iostream.h>
is from a pre-standard implementation of the language, though it is usually shipped so as to maintain backwards compatibility with older code.
Try with:
#include <iostream>
Instead of:
#include <iostream.h>
iostream.h is an old style header in which all functions are exposed in global namespace. naturally in such a case, using namespace std may not work since std namespace is probably not exposed by iostream.h header (in this compiler). As explained above, try with # include which is a new style C++ standard library header. (thanks Shailesh Kumar for the comment! included it in the answer).