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).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With