c++compiler-warnings

Assignment in (else) if statement triggers warning in MSVC but not in gcc / clang


This code snippet triggers a warning in MSVC (VS2022 17.10.2).

int m = 0;
if(int i = m)
    // ...
else if (int i = m) // warning C4456: declaration of 'i' hides previous local declaration
    // ...

Tested gcc / clang in wandbox

Is MSVC's warning correct? Is the hiding happening also in gcc / clang, but they are not warning? I would expect consistent behavior across compilers.


Solution

  • Yes, int i = m in the else branch shadows the int i = m from the if branch. Consider that there is actually no "else if" but it's just another if nested in the else branch and i is in scope for the whole outer if statement. For example:

    if (int i = 42) {
        // something 
    } else if (false) {
        std::cout << i; // i is in scope here
    }
    

    I would expect consistent behavior across compilers.

    That's a faulty expectation. Warnings are not mandated and compiler-specific by nature. A compiler can warn you as much as it wants or not. It's just a matter of quality of implementation that a compiler produces reasonable warnings and provides documentation on how to dis/enable them.

    All compilers are correct here.

    With gcc and clang you get the expected warning with -Wshadow: https://godbolt.org/z/rEc9qf7K8

    (Note that neither gcc nor clang include -Wshadow in -Wall. -Wall does not, as the name might suggest, enable all warnings, but only the most common ones)