2010-06-02 2 views
15

В следующем примере:gcc -Wshadow слишком строг?

class A 
{ 
    public: 
    int len(); 
    void setLen(int len) { len_ = len; } // warning at this line 
    private: 
    int len_; 
}; 

GCC с -Wshadow выдает предупреждение:

main.cpp:4: warning: declaration of `len' shadows a member of `this' 

функции Len и целого Len имеют различного типа. Почему предупреждение?

Update

Я вижу, есть широкий cocensuse, что "теневые" средства. И с формальной точки зрения компилятор делает именно то, что это значит.

Однако ИМХО, флаг нецелесообразен. Например, обычно используется сеттер/добытчика идиомы:

class A { 
    void prop(int prop); // setter 
    int prop() const;  // getter 

    int prop; 
}; 

Было бы хорошо, если будет предупреждение флаг, который не будет выдавать предупреждение в случае, но предупредит в случае «Int А» скрывает «Int а».

Добавление -Wshadow в мой старый код вызывает множество предупреждений, время от времени Я обнаруживаю ошибки, вызванные проблемой «затенения».

Я не против, как это будет называться «-Wmuch_more_practical_and_interesting_shadow» или «-Wfoooooo».

Итак, есть прочее gcc предупреждающий флаг, который делает то, что я описал?

Update 2

Не только мне думает -Wshadow как-то не полезно link text. Я не одинок :) Менее строгие проверки могут быть намного полезнее.

+4

Ваша «обычно используемая идиома» - это даже не юридический код. –

ответ

14

Это, похоже, решается в новых версиях GCC.

From version 4.8 changelog:

The option -Wshadow no longer warns if a declaration shadows a function declaration, 
unless the former declares a function or pointer to function, because this is a common 
and valid case in real-world code. 

И он ссылается на мысли Линуса Торвальдса на тему: https://lkml.org/lkml/2006/11/28/253

К сожалению новейший составитель встраиваемой системы, где я в настоящее время работает по-прежнему базируется на GCC 4.6.

+0

+1 для этого ответа. -1 для GCC для этого решения, хотя! –

+5

На самом деле с GCC 4.8.2 эта проблема с -Wshadow все еще существует. Если вы прочитали эту проблему с bugzilla: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=57709, это подтвердило, что функции _member_, которые названы так же, как и параметр функции, как в вашем примере, все еще генерируют теневое предупреждение. Начиная с GCC 4.8, только свободные функции имеют эту ошибку. Похоже, нам нужно подождать, пока GCC 5.0 не будет работать так, как вы ожидали. – ScottG

15

Тот факт, что параметр имеет другой тип от функции-члена, не влияет на то, что параметр затеняет функцию-член.

Почему вы ожидаете, что не будет предупреждения об этом?

+0

Мне интересно в случаях, когда переменная скрывает переменную. Это потенциально ошибка. Но случай, когда переменная «скрывает» функцию, просто не интересна. – dimba

+4

@idimba: Я не согласен. Указатель функции может быть сохранен в переменной. Также переменная может иметь определенную для нее 'operator()', поэтому ее можно вызвать как функцию. – Troubadour

+7

Возможно, это не интересно, но это * * затенение. И предупреждение называется -Wshadow, а не -Winteresting. Поэтому я ожидаю, что он будет предупреждать, когда одно имя скрывает другое, а не когда @idimba считает код «интересным». – jalf

6

Он делает именно то, что говорит на коробке. Он предупреждает вас о затенении.

Внутри функции setLen два символа находятся в области с одинаковым именем. len - это имя параметра функции, а также имя функции.

shadows имя другого, поэтому, когда вы пишете код, относящийся к len, вы не можете получить желаемый результат. Поскольку вы попросили компилятор предупредить вас о символах shadowing для всех остальных, об этом вас предупреждает.

9

Я не понимаю, почему вы настаиваете только на некоторых конкретных типах затенения. Тень - это затенение, а опасность его одинакова, даже если типы различны и даже если переменная теневая функция, как в вашем случае. Опасность затенения заключается в том, что код может сделать что-то отличное от того, что его автор хотел этого сделать.

Это, BTW, может легко произойти, когда переменная затеняет функцию, поскольку в C++ различие между ними намного тоньше, чем может показаться на первый взгляд.

Например, здесь переменная тень функции

struct L { 
    void operator()(); 
}; 

struct A { 
    void len(); 

    A(L len) { 
    len(); 
    // Intended to call the member function. Instead got a call to the functor 
    } 
}; 

, и я думаю, что это довольно очевидно, что из-за затенение код могли бы сделать что-то, что автор не намерен это делать.

2

Да, мы можем настроить это предупреждение, чтобы предупредить, только если затенение может быть опасным. Например, не тень для

ничтожного набора (INT что) .. ИНТА, что() Const ..

но предупреждает для локальной переменной shadowning и для примера функтора выше.

Чтобы быть более точным, предупреждайте, когда затенение может быть опасным, когда намерение писателя кода может быть нечетким. В случае параметра int и функции-члена с тем же именем ясно, что автор не хочет, чтобы член вызывался, когда он ссылается на параметр.

Я нахожу это предупреждение о тене, чтобы быть хорошей идеей, очень полезно, просто нужно немного подумать, чтобы не предупредить о совершенно безопасных и ясных случаях. Я, например, могу жить с аргументами, необходимыми для получения префикса или чего-то еще, но я предпочитаю чистые и простые имена.

Смежные вопросы