https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82797

            Bug ID: 82797
           Summary: Suggest -Wshadow suppression for nested if/else
           Product: gcc
           Version: 7.2.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: wsnyder at wsnyder dot org
  Target Milestone: ---

Created attachment 42518
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=42518&action=edit
shadow.cpp

I would like to suggest that code similar to the following under -Wshadow:

    if (ClassA* thing3 = geta()) {
        operate(thing3);
    }
    else if (ClassB* thing3 = getb()) {  // Suggest no warning here
        operate(thing3);
    }

Not throw a:

   warning: declaration of 'thing2' shadows a previous local [-Wshadow]

While the warning is correct in that the else if's thing3 does in fact shadow
the first if's definition of thing3, this coding style makes it fairly clear
that the intent is to properly redefine thing3, and it is hard to imagine how
there could be a mistake as to which thing3 is being referred to.

Furthermore, there is no clean way to work around this warning; e.g. if the
"else if"'s thing3 is renamed it will only make the code less readable and
potentially lead to other errors e.g.:

    if (ClassA* thing3 = geta()) {
        operate(thing3);
    }
    else if (ClassB* thing3b = getb()) {  // used thing3b so no shadow warning
        operate(thing3);  // Is this really thing3, or should it have been
thing3b?
    }

Fixing the warning clearly makes the code less similar and more bug prone,
opposite of the intent of the warning.

However IMO this does, and should continue to result in a shadow warning:

    if (ClassA* thing3 = geta()) {
        operate(thing3);
    }
    else {
        ClassB* thing3 = getb();
        operate(thing3);
    }

Thanks for your consideration. A test case is attached.

Reply via email to