gcc -Whadow слишком строг? - PullRequest
       5

gcc -Whadow слишком строг?

16 голосов
/ 02 июня 2010

В следующем примере:

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 имеют разные типы. Почему предупреждение?

Обновление

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

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

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

   int prop;
};

Было бы хорошо, если бы был флаг предупреждения, который не будет выдавать предупреждение в этом случае, но будет предупреждать в случае, если "int a" скрывает "int a".

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

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

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

Обновление 2

Я не единственный, кто думает - Тень как-то бесполезна текст ссылки . Я не одинок :) Менее строгая проверка может быть гораздо полезнее.

Ответы [ 5 ]

17 голосов
/ 21 марта 2013

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

С версии 4.8 изменения

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.

15 голосов
/ 02 июня 2010

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

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

9 голосов
/ 02 июня 2010

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

Это, кстати, может легко произойти, когда переменная скрывает функцию, поскольку в 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
  }
};

, и я думаю, что совершенно очевидно, что из-за затенения код может делать то, что автор не намеревался делать.

6 голосов
/ 02 июня 2010

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

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

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

2 голосов
/ 22 декабря 2010

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

void set (int what) .. int what () const ..

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

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

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

...