Rule 14–6–1 and injected-class-names

Moderators: david ward, misra cpp

James Widman
Posts: 9
Joined: Fri Jun 20, 2008 9:17 pm
Company: Gimpel Software

Rule 14–6–1 and injected-class-names

Postby James Widman » Thu Jul 03, 2008 5:56 pm

Hi all,

Rule 14–6–1 says:

"In a class template with a dependent base, any name
that may be found in that dependent base shall be
referred to using a qualified-id or this->"

But then the example code contains this line:

Code: Select all

    typename B<T>::TYPE t2 = 0; // Compliant - explicit use base TYPE

But I don't think that's correct, because although TYPE is qualified, B is not. I think this line should be moved into A<T>::f1() and commented with "Non-compliant: B is unqualified". And add the line:

Code: Select all

    typename ::B<T>::TYPE t2 = 0; // Compliant - explicit use of B and of TYPE.

...to f2().

Here's an example where it makes a difference:

Code: Select all

template <class T>
struct B  {
    static void j();
};

namespace N {
    template <class T>
        struct B {
            static void j();
        };

}

template <class T>
struct A : public N::B<T> {
    static void f1 ( ) {
        A::template B<T>::j(); // compliant
        A::B::j(); // compliant
    }
    static void f2 ( ) {
        B<T>::j(); // non-compliant
    }
};

void h() {
    A<int>::f1(); // calls ::N::B<int>::j() twice
    A<int>::f2(); // calls ::B<int>::j() once
}
James Widman
--
Gimpel Software
http://gimpel.com

James Widman
Posts: 9
Joined: Fri Jun 20, 2008 9:17 pm
Company: Gimpel Software

Re: Rule 14–6–1 and injected-class-names

Postby James Widman » Mon Jul 07, 2008 6:59 pm

For what it's worth, at least one implementation binds the call 'B<T>::j()' to ::N::B<int>::j() in the instantiation of ::A<int>::f2(), but it should bind to ::B<int>::j(). So it seems pretty clear that we need to regard the use of 'B' in f2() as non-compliant.

Also, since submitting the above post, I've found that some popular implementations don't correctly handle the uses of injected-class-names in the class template A above, so MISRA may want to say something about that. For example, MISRA may want to say that the 'safe' way to refer to a base class within a derived class involves a member typedef name; e.g.:

Code: Select all

struct D : public N::B<T> {
    typedef ::N::B<T> B1; //compliant

    typedef N::B<T> B2; // non-compliant
       // ('N' could be found in the base at instantiation time by a buggy compiler.)

    typedef B<T>  B3; // non-compliant

    void f ( ) {
        B1::j(); // compliant
       // (unqualified lookup for 'B1' does not go up against a dependent base)
    }
};
James Widman
--
Gimpel Software
http://gimpel.com

richard_corden
Posts: 4
Joined: Thu Sep 22, 2005 9:33 am
Location: Hersham

Re: Rule 14–6–1 and injected-class-names

Postby richard_corden » Wed Jul 16, 2008 4:59 pm

I agree. The example should probably be changed to:


Code: Select all

typename A<T>::B<T>::TYPE t2 = 0; // Compliant - explicit use of B and of TYPE.


and for simplicity even:

Code: Select all

typename A::B::TYPE t2 = 0; // Compliant - explicit use of B and of TYPE.


'A' and 'A<T>' match the current specialization.

The rule text (or at least rationale) should be updated to highlight that this is required.


Regards,

Richard
--
Richard Corden
Programming Research Ltd.
[email protected]
+ 44 845 0048478

misra cpp
Posts: 145
Joined: Mon Jun 02, 2008 1:55 pm
Company: MISRA

Re: Rule 14–6–1 and injected-class-names

Postby misra cpp » Tue Oct 11, 2016 11:11 am

A future edition or Technical Corrigendum will consider changes along the lines suggested by Richard Corden's post
Posted by and on behalf of
the MISRA C++ Working Group


Return to “6.14 Templates (C++)”

Who is online

Users browsing this forum: No registered users and 1 guest