3

This code compiles in MSVC (19.00.23918) but GCC doesn't like it unless I use this-> access to member operator when I call Detach_Internal().

Is GCC catching a potential bug here that MSVC isn't? As a general rule is it a better idea to use this-> at all times when referencing functions in base classes?

Note GCC will compile it with -fpermissive.

#include <memory>

namespace Events
{
    template<typename T>
    class EventBase
    {
    protected:

        void Detach_Internal(std::weak_ptr<void> const & p)
        {

        }
    };

    template<typename T>
    class Event : public EventBase<T>
    {
    public:

        void Detach(std::weak_ptr<void> const & p)
        {
            Detach_Internal(p);
        }
    };
}


int main(void)
{
    auto event = std::make_unique<Events::Event<void()>>();    
}

33:30: error: there are no arguments to 'Detach_Internal' that depend on a template parameter, so a declaration of 'Detach_Internal' must be available [-fpermissive]

Robinson
  • 9,666
  • 16
  • 71
  • 115
  • 2
    I have never seen "don't like it" as compiler message. –  Aug 22 '17 at 16:06
  • Those who know, know :). Added the error message. – Robinson Aug 22 '17 at 16:10
  • Reopend, not sure if the dupe is actually proper. Linking here as a reference: https://stackoverflow.com/questions/1120833/derived-template-class-access-to-base-class-member-data – NathanOliver Aug 22 '17 at 16:10
  • It's certainly relevant but the issue here is that Visual Studio doesn't warn about it. I'm wondering how much of my codebase is "bad" in this sense. – Robinson Aug 22 '17 at 16:13
  • Visual Studio **is not** the compiler, it's the IDE and the only thing it provides is a GUI for setting compiler options. Specify your compiler (presumably MSVC) and its version instead. For me, MSVC 19.11.25506 compiles this fine, even with `/permissive-`. – tambre Aug 22 '17 at 16:15
  • @tambre Please read the question. – Robinson Aug 22 '17 at 16:18
  • Oops. My point about instead giving the actual compiler version, instead of the IDE marketing name still stands, though. I suggest you fix that for people from the future. – tambre Aug 22 '17 at 16:25
  • Took me a while to get the compiler version. Never used the command line before (which is where it shows). Anyway question edited to give it. – Robinson Aug 22 '17 at 16:36

1 Answers1

8

Is GCC catching a potential bug here that VS isn't? As a general rule is it a better idea to use this-> at all times when referencing functions in base classes?

GCC is correct. You should add this-> when referring names in dependent base class (i.e. EventBase<T>, which depends on template parameter T).

Otherwise as a nondependent name, Detach_Internal won't be looked up in dependent base class EventBase<T>.

To solve the issue you can make the name Detach_Internal dependent, then it will be looked up at the time of instantiation, at that time the exact base class template specialization is fixed. e.g.

this->Detach_Internal(p);
EventBase<T>::Detach_Internal(p);
using EventBase<T>::Detach_Internal;
Detach_Internal(p);
Toby Speight
  • 27,591
  • 48
  • 66
  • 103
songyuanyao
  • 169,198
  • 16
  • 310
  • 405
  • Could I ask you to speculate as to why the Visual Studio compiler is OK with it but GCC isn't (without the permissive switch)? Is it a standards compliance issue? – Robinson Aug 22 '17 at 16:17
  • 3
    @Robinson: Yes it's a standards compliance issue, specifically related to "two phase template lookup". Microsoft supported templates in C++ before they were part of the standard, and never quite got around to updating that particular aspect of their compilers to follow the (different) standard rules. Two-phase template lookup is expected to be the last thing they get right, due to how complicated they said the existing template lookup code is. – Ben Voigt Aug 22 '17 at 16:20
  • @Robinson As Ben commented, according to the rule of [two phase lookup](http://en.cppreference.com/w/cpp/language/dependent_name#Lookup_rules), VS is wrong and this might be (or should be regarded as) a bug. – songyuanyao Aug 22 '17 at 16:27
  • 4
    This is not a "bug" in the sense that it is by accident, but rather still "not yet implemented" after 20 years. [The release notes for the August release](https://blogs.msdn.microsoft.com/vcblog/2017/08/11/c17-features-and-stl-fixes-in-vs-2017-15-3/) says *"Two-phase name lookup is partially implemented in VS 2017 15.3, and a detailed blog post will be available very soon."*. – Bo Persson Aug 22 '17 at 17:22
  • @BoPersson Yes, this is the most accurate explanation to OP's doubt. – songyuanyao Aug 22 '17 at 17:25
  • @BoPersson Ah, interesting. I'm sure a lot of code at work is going to break when that finally gets done. Job security :) – Robinson Aug 22 '17 at 18:30