Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does the compiler warn about shadowing a member in initalization lists?

Take a constructor parameter with the same identifier as the data member it's initializing. If the two are used inside an initialization list, it would be considered safe, and "shadowing" would not occur.

However, take the following example:

struct A{
  A(int a, int b);
  int a, b;
};

A::A(int a, int b)
: a(a)
, b(b)
{}

int main(){}

warnings seen with g++:

g++ -Wshadow --std=c++1z -o main main.cpp 
main.cpp: In constructor ‘A::A(int, int)’:
main.cpp:8:18: warning: declaration of ‘b’ shadows a member of ‘A’ [-Wshadow]
 A::A(int a, int b)
                  ^
main.cpp:4:10: note: shadowed declaration is here
   int a, b;
          ^
main.cpp:8:18: warning: declaration of ‘a’ shadows a member of ‘A’ [-Wshadow]
 A::A(int a, int b)
                  ^
main.cpp:4:7: note: shadowed declaration is here
   int a, b;

warnings seen with clang:

clang++ -Wshadow --std=c++1z -o main t.cpp
main.cpp:8:10: warning: declaration shadows a field of 'A' [-Wshadow]
A::A(int a, int b)
         ^
main.cpp:4:7: note: previous declaration is here
  int a, b;
      ^
main.cpp:8:17: warning: declaration shadows a field of 'A' [-Wshadow]
A::A(int a, int b)
                ^
main.cpp:4:10: note: previous declaration is here
  int a, b;

I'm not doing anything to the data members in the body of the constructor-- so why am I getting these warnings?

I'd like to leave the warning flag enabled to catch legitimate mishaps, but these particular cases are causing too much false noise. Is there validity in these warnings?

like image 628
Trevor Hickey Avatar asked Jan 20 '16 09:01

Trevor Hickey


1 Answers

Although you aren't doing anything where the shadowing might hurt you now, you are setting yourself up for some maintenance headaches.

If Maintainer Joe comes along and and needs to make a change like this:

A::A(int a, int b)
: a(a)
, b(b)
{
    storeReference(a);
}

Oops! He's just stored a reference to the parameter rather than the data member.

The compiler isn't telling you you're doing anything wrong per se, it's telling you that you might want to change your names so that you don't have issues in the future.

I, for one, would recommend choosing a naming convention to disambiguate and sticking to it. Personally, I like to put m_ on the front of member data, but others prefer to suffix _ to the member data or the constructor param.

like image 194
TartanLlama Avatar answered Sep 22 '22 10:09

TartanLlama