Main Content

MISRA C++:2023 Rule 6.4.3

A name that is present in a dependent base shall not be resolved by unqualified lookup

Since R2024b

Description

Rule Definition

A name that is present in a dependent base shall not be resolved by unqualified lookup.

Rationale

When a class template derives from another class template, there might be confusion arising from the use of names that exist in both the base template and the current scope or namespace. When the same name exists in the base class template and a namespace that contains the classes, the scope resolution of these names is dependent on the compiler, which might be contrary to developer's expectation. To avoid confusion, use fully qualified id or this-> to explicitly disambiguate the intended object when such a name conflict exists.

Polyspace Implementation

Polyspace® flags names for which all of these conditions are true:

  • The name exists in the base class.

  • The name exists in a namespace that contains the base class.

  • The name is used without qualified id or this->.

Troubleshooting

If you expect a rule violation but Polyspace does not report it, see Diagnose Why Coding Standard Violations Do Not Appear as Expected.

Examples

expand all

In this example, the names Type and bar are defined both in the namespace NS0 and within the class template Base. The class template Derived derives from Base. In Derived::foo1(), these names are used without using the fully qualified names or this->. It is not clear whether the TYPE in Base::foo1 resolves to NS0::TYPE or Base::TYPE. You might get different results depending on the implementation of the compiler. Polyspace flags these ambiguous statements.

In Derived::foo2(), TYPE and bar are invoked by using their fully qualified name or this->. By using qualified names or this->, the ambiguity in scope resolution is bypassed. Polyspace does not flag these uses.

typedef signed   int          int32_t;
namespace NS0{
	typedef int32_t TYPE;

	void bar( );
	namespace NS1{
		namespace NS{
			
			template <typename T>
			class Base;
			template <typename T>
			class Derived : public Base<T>
			{
				void foo ( )
				{
					TYPE t = 0;                           // Noncompliant
					bar ( );                                // Noncompliant
				}
				void foo2 ( )
				{
					NS0::TYPE t1 = 0;                      // Compliant
					NS0::bar ( );                            // Compliant
					typename Base<T>::TYPE t2 = 0; // Compliant
					this->bar ( );                // Compliant
				}
			};
			template <typename T>
			class Base
			{
			public:
				typedef T TYPE;
				void bar ( );
			};
			template class Derived<int32_t>;
		}
	}
}

Check Information

Group: Basic Concepts
Category: Required

Version History

Introduced in R2024b