6

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.VS pic 1

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

vladon
  • 8,158
  • 2
  • 47
  • 91
  • Did you try to compile the code? IntelliSense highlights every second line in my project, and it actually compiles fine. – Rakete1111 Jun 11 '17 at 13:57
  • @Rakete1111 It compiles fine. But this Intellisense curly underline bothers me. – vladon Jun 11 '17 at 13:58
  • 2
    @Rakete1111 And please DO NOT delete "visual-studio-2017" tag, this question is specific only to this version. – vladon Jun 11 '17 at 14:00
  • Intellisense is notoriously buggy with C++ code. – Jonathon Reinhart Jun 11 '17 at 14:00
  • @vladon Well, I guess you're right. Sorry, I acted too quickly :) – Rakete1111 Jun 11 '17 at 14:00
  • @JonathonReinhart Ok, but I asked about known solution, for example, workaround in settings, patching headers, etc. – vladon Jun 11 '17 at 14:01
  • 5
    So what you're saying is, you only get ugly squiggles when you write `using namespace std`? That would make this the best new feature of VS 2017. – Cody Gray - on strike Jun 11 '17 at 14:02
  • @EdHeal - The question you linked wasn't remotely a duplicate. None of the answers there provide any help here. – StoryTeller - Unslander Monica Jun 11 '17 at 14:03
  • @CodyGray :-) But I need to maintain legacy code. VS 2017 is great, but this thing makes me crazy. – vladon Jun 11 '17 at 14:04
  • There's always the "turn off intellisense" solution. – DeiDei Jun 11 '17 at 14:04
  • @DeiDei Turning off Intellisense is bad solution :) – vladon Jun 11 '17 at 14:04
  • 1
    Well by the power of sense and profit, removing using namespace std; will bring you two things (no squiggles and fixing all the other problems with the statement) and turning off intellisense will bring you one thing (no squiggles). From all the economics I learned in CS university, I'd say the first is more profitable ;) – DeiDei Jun 11 '17 at 14:07
  • @DeiDei Yeah, thank you :-) May be I will do this. But it is definitely a bug, and I think not in Intellisense, but in C++ Linux headers in VS. – vladon Jun 11 '17 at 14:10
  • @vladon If it actually compiles fine, how can it be a bug in the headers? If Intellisense works differently from the real compiler, surely it must be an Intellisense bug? –  Jun 11 '17 at 14:13
  • @hvd Because it compiles with other headers (system one) on target Linux system – vladon Jun 11 '17 at 14:17
  • 2
    *a bug in Linux headers causes squiggly red lines in itellisense* Do you realise **what** Linus would answer to that? – n. m. could be an AI Jun 11 '17 at 14:18
  • 1
    @n.m. Read again carefully: bug in headers used for Linux projects in VS. Anyway, do you know what Linus would say about C++ itself? – vladon Jun 11 '17 at 14:19
  • 1
    Ah you mean Microsift headers for Linux projects? Yeah that could be their bug. C++ in the kernel? Yes I know what he said, I have read that. C++ elsewhere? Well he admitted he was using KDE (and, horrors, gcc itself!) so I guess no, I don't know. – n. m. could be an AI Jun 11 '17 at 14:26
  • @n.m. I am not Linus' apostle or prophet, so please stop about him. – vladon Jun 11 '17 at 14:27
  • Yes `defined (size_t))` certainly looks fishy, `size_t` is not supposed to be a macro. – n. m. could be an AI Jun 11 '17 at 14:30
  • @vladon Ah wait, that was not clear to me, sorry for misunderstanding. You're saying the error is shown with the Microsoft headers, but those Microsoft headers are *only* used for Intellisense, the actual build doesn't use them, is that right? Anyway, the specific thing those headers do (two separate identical typedefs in different namespaces) does generally work (try it: `typedef int Foo; namespace Bar { typedef int Foo; } using namespace Bar; Foo main() { return Foo{0}; }`), so I'm still not convinced it's a bug in the headers. –  Jun 11 '17 at 14:31
  • @n.m. I thought it is correct to use `defined(not_macro_symbol)` in preprocessor. – vladon Jun 11 '17 at 14:32
  • @hvd So how this works for Windows projects (with `using namespace std;`) ? – vladon Jun 11 '17 at 14:32
  • @vladon The headers that are used for Windows projects may happen to avoid / work around the issue, for instance by using `using` to make the same typedef available in multiple namespaces. –  Jun 11 '17 at 14:34
  • Hmm you are right. It's a gcc header anyway, not Microsoft's. – n. m. could be an AI Jun 11 '17 at 14:34
  • 1
    IntelliSense still uses the [EDG](https://www.edg.com/) compiler frontend. At the time Microsoft switched to using it, it was quite a bit ahead of Microsoft's compiler frontend with respect to standards compliance. Those times are gone, and we are now left with a situation, where IntelliSense and the actual compiler use different rule sets (and probably different environments as well). Different observable behavior is a logical consequence. Until Microsoft decide to use the same code for IntelliSense and compiling code, there's little hope for the situation to change. – IInspectable Jun 11 '17 at 14:58
  • I'm getting this "error" without `using namespace std;` from conflicting definitions in `vcruntime.h` and `CodeAnalysis\sourceannotations.h` – robsn Aug 07 '17 at 09:55

1 Answers1

6

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).

n. m. could be an AI
  • 112,515
  • 14
  • 128
  • 243
  • 1
    It is accepted actually by gcc (because linux projects from vc 2017 are compiled remotely on linux target system) – vladon Jun 11 '17 at 15:18
  • Oh I see. This makes sense. – n. m. could be an AI Jun 11 '17 at 15:20
  • 7.1.3/3 doesn't look like it applies here. In your second `typedef int moo;`, `foo::moo` is not in scope. –  Jun 11 '17 at 15:45
  • @hvd that's basically what I'm saying too. – n. m. could be an AI Jun 11 '17 at 15:48
  • [namespace.udir]p6 looks meant to address this: "If name lookup finds a declaration for a name in two different namespaces, and the declarations do not declare the same entity and do not declare functions, the use of the name is ill-formed." Here, both declare the same entity. But, it conflicts with [basic.lookup]p1: "Name lookup shall find an unambiguous declaration for the name (see 10.2). Name lookup may associate more than one declaration with a name if it finds the name to be a function name; [...]" This requires a unique *declaration* rather than a unique *entity*. –  Jun 11 '17 at 15:52
  • 1
    @hvd if this isn't an open issue in the standard, it should be. – n. m. could be an AI Jun 11 '17 at 16:15
  • @hvd "Name lookup may associate more than one declaration with a name if it finds the name to be a function name" this doesn't look rigt, most entities can be redeclared any number if times. – n. m. could be an AI Jun 11 '17 at 16:18
  • @n.m. Indeed. And it's not like later declarations have no effect and are discarded: `extern int a[], b[4]; int a[4], b[]; int main() { return sizeof a - sizeof b; }` only works if *both* `a` and `b` have the array bound found. For one it is in the original declaration, for the other it is in the definition. –  Jun 11 '17 at 16:46
  • @CodyGray Please read again. **MSVC rejects this code**. The real compiler that accepts it is apparently gcc. Of course it is different from IntelliSense. – n. m. could be an AI Jun 12 '17 at 11:00
  • MS answers 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 – vladon Jun 13 '17 at 08:44
  • Fact 1: OP's compiler accepts the code. Fact 2: MSVC in my experiments rejects the code. Fact 3: gcc accepts the code. Fact 4: IntelliSense rejects the code. Fact 5: MSVC, gcc and IntelliSense all use different compiler cores. Fact 6: OP's real compiler (as opposed to IntelliSense which is not a real compiler, just a checker) is actually gcc and not MSVC. It's the fact 6 that I wasn't aware of initially, not any of 1-5. This is reflected in comments. – n. m. could be an AI Jun 14 '17 at 12:11
  • Hmm, I wasn't aware of fact 6 either. I still don't see where that fact is given, but that's okay. It doesn't matter to me. Sorry to have bothered you. – Cody Gray - on strike Jun 14 '17 at 12:15