Ambiguous symbol in VS but not OSX


#1

Hi,

My colleague created a project in the new jucer on the Mac and has been successfully developing in Xcode there. But now I’m trying to compile in Visual C++ 2010 Express (which converted the VS2008 solution), and I’m getting “ambiguous symbol” errors.

It seems as if the symbol Component is being referenced in two different ways - but how? And how does this work on the Mac?

Do note that both the Xcode and Visual C++ projects were entirely created by the experimental JUCER and we’ve made it a point never to edit them.

We deliberately have very few settings changed in the experimental JUCER project. We thought it might be one of the “include Juce” settings but we tried all four of them with the same results.

Can someone point me to what might be wrong? Here’s a typical error message (one of many similar):

1>c:\documents and settings\administrator\my documents\visual studio 2010\projects\rec-rec-459173acddb4f84fdcd2d875390693e1cf022a4a 2\src\rec\app\componentcontainer.h(10): error C2872: ‘Component’ : ambiguous symbol
1> could be 'c:\documents and settings\administrator\my documents\visual studio 2010\projects\rec-rec-459173acddb4f84fdcd2d875390693e1cf022a4a 2\src\rec\app\recwindow.h(7) : Component’
1> or 'c:\documents and settings\administrator\my documents\visual studio 2010\projects\juce\juce_amalgamated.h(12353) : juce::Component’
1> c:\documents and settings\administrator\my documents\visual studio 2010\projects\rec-rec-459173acddb4f84fdcd2d875390693e1cf022a4a 2\src\rec\app\componentcontainer.h(62) : see reference to class template instantiation ‘rec::ComponentContainer’ being compiled

Thanks,
Warren


#2

You seem to be getting yourself in quite a twist about juce includes, etc, but didn’t you actually read the error message properly? It’s very clearly telling you that you’ve defined your own class called “Component” on line 7 of some file called “recwindow.h”.

In this case, the reason it would have worked on the mac is because I use a macro to replace “Component” with “juce::Component”, to avoid a similar name collision on OSX. On windows, that macro isn’t active, so you’d need to add the namespace explicitly. Or just don’t use “Component” as a class in your own code!


#3

Hello. This is my code in question, in fact! Even before looking at the code, I can assure you that that is not the issue in such a raw way - because how would it work on OS/X and not on Windows, hmmm?? (And there are certainly no classes named Component in my code… :-D)

Looking at my code, I believe I’ve figured out what’s going on - which is that the juce code is being included in the juce namespace in a Windows build, but not in OS/X. Since we’re using the new experimental JUCER to generate both projects, this shows a difference between the two systems.

I have a tendency to use forward references a lot in my C++ code, to keep compile times down and to reduce linkages between programs.

This turns out to not be an effective strategy for JUCE, mainly because in practice you always have to include everything. (Yes, I do think this is also a minor software defect, but is as nothing compared to the amazing strengths of the package!)

I wrote RecWindow.h very early in my JUCE-fiddling process, so I was still attempting to do this.

[code]// …

class Component;

namespace xxxxx {

class RecWindow : public DocumentWindow {
// …
::Component* taskbarIcon;
};

} // namespace[/code]

So what must be happening is that “Component” is ::Component under OS/X but juce::Component and ::Component on Windows. Or perhaps it’s that the C++ compiler’s resolution of these names is subtly different between the systems.

Regardless, the solution is simple - just include juce_amalgamated.h and don’t be so fancy. :smiley:


#4

Interesting, that wasn’t quite it, though still not sure exactly what was/is going on.

When I made what seemed to be a correct fix and tested it in OS/X, that started failing compilation, apparently not recognizing Component at all any more.

I noted that another, apparently disjoint class (“GenericApplication”) was in my namespace xxxxx::juce (I did that deliberately, I use namespaces a lot to segment my code) and moved that into other class namespace xxxxx. That allowed everything to compile on OS/X - but even seeing the fix, I don’t see why it failed before. I strongly suspect it’ll also now work on Windoze (and will update this thread of course if it doesn’t).

I’m not quite interested enough to track it down (guess: Koenig resolution interacting with the tricks JUCE does to be back compatible with old code that isn’t using the namespace ::juce??) but suggest “don’t do that” - if you’re working with JUCE, don’t call any namespace juce, even if it’s a nested namespace and supposedly can’t interfere with juce’s namespace.

(I feel that a few "::"s thrown into JUCE somewhere might fix this but also feel that I might be the only person ever to run into this… :-D)


#5

Maybe I didn’t explain myself very well in my earlier post - what I was trying to say was that there’s a cunning OSX-only macro that redefines “Component” as “juce::Component”, to avoid conflicts in the OSX headers - it’s obviously this that’s causing all the confusion, and you might want to use the JUCE_DONT_DEFINE_MACROS flag to disable it. Have a look in juce.h for more info on it.


#6

Too late, it’s already fixed! :smiley:

I think that “cunning macro” as you say must be at issue.

I’m glad you have to deal with these cross-platform issues and we can just use the fruits of your labour… :smiley: