2010-06-02 7 views
15

En el siguiente ejemplo:gcc -Wshadow es demasiado estricto?

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

gcc con cuestión -Wshadow una advertencia:

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

función len y número entero len son de diferente tipo. ¿Por qué la advertencia?

actualización

veo que hay una amplia cocensuse lo que significa "sombra". Y desde el punto de vista formal, el compilador hace exactamente lo mismo.

Sin embargo, en mi humilde opinión, la bandera no es práctica. Por ejemplo comúnmente usado setter/getter idioma:

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

    int prop; 
}; 

Sería bueno si habrá una señal de aviso que no va a emitir advertencias en el caso, pero advertirá en caso de que "int a" oculta "int un".

Agregando -Wshadow en mi código heredado emiten toneladas de advertencias, mientras que de vez en cuando Descubro errores causados ​​por el problema de "ocultación".

No me importa cómo se llamará "-Wmuch_more_practical_and_interesting_shadow" o "-Wfoooooo".

Entonces, ¿hay otro bandera de advertencia de gcc que hace lo que describí?

Actualización 2

No sólo yo piensa -Wshadow alguna manera no es útil link text. No estoy solo :) Las comprobaciones menos estrictas podrían ser mucho más útiles.

+4

Su "modismo de uso común" ni siquiera es código legal. –

Respuesta

14

Esto parece estar resuelto en las versiones más nuevas de 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. 

Y hace referencia a los pensamientos de Linus Torvalds sobre el tema: https://lkml.org/lkml/2006/11/28/253

Desafortunadamente el nuevo compilador del sistema embebido, donde trabajo actualmente se sigue basando en gcc 4.6.

+0

+1 para esta respuesta. -1 a GCC por esta decisión, sin embargo! –

+5

En realidad a partir de GCC 4.8.2 este problema con -Wshadow todavía está allí. Si lee este problema de bugzilla: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=57709 se confirma que _member_ funciones que tienen el mismo nombre que un parámetro de función, como en su ejemplo, aún generan el advertencia de sombra. A partir de GCC 4.8, solo las funciones gratuitas tienen este error suprimido. Parece que tenemos que esperar hasta que GCC 5.0 tenga este trabajo de la manera esperada. – ScottG

15

El hecho de que el parámetro tenga un tipo diferente de la función miembro no afecta el hecho de que el parámetro sombrea la función miembro.

¿Por qué esperar que no haya una advertencia al respecto?

+0

Soy interesante en los casos cuando la variable oculta variables. Esto potencialmente un error. Pero el caso cuando la variable "oculta" una función simplemente no es interesante. – dimba

+4

@idimba: No estoy de acuerdo. Un puntero de función puede almacenarse en una variable. También una variable puede tener un 'operador()' definido para que pueda invocarse como una función. – Troubadour

+7

Puede que no sea interesante, pero * está * sombreado. Y la advertencia se llama -Wshadow, no -Winteresting. Así que espero que advierta cuando un nombre oculta a otro, no cuando @idimba cree que el código es "interesante". – jalf

6

Hace exactamente lo que dice en la caja. Te advierte sobre las sombras.

Dentro de la función setLen, hay dos símbolos en el alcance que comparten el mismo nombre. len es el nombre de un parámetro de función, y también el nombre de una función.

One sombras el nombre del otro, por lo que cuando escribe código que hace referencia a len, es posible que no obtenga el resultado que deseaba. Dado que le pidió al compilador que le advierta acerca de los símbolos sombreando entre sí, esto es lo que le advierte.

9

No entiendo por qué insiste solo en algunos tipos específicos de sombreado. El sombreado es un sombreado, y los peligros son los mismos, incluso si los tipos son diferentes e incluso si una variable sombrea una función, como en su caso. El peligro de sombreado es que el código podría hacer algo diferente de lo que su autor quería que hiciera.

Esto, por cierto, puede suceder fácilmente cuando una variable está sombreando una función, ya que en C++ la distinción entre los dos es mucho más delgada de lo que podría parecer a primera vista.

Por ejemplo, aquí una variable sombras una función

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 
    } 
}; 

y creo que es bastante obvio que debido a la sombra del código podría hacer algo que el autor no tenía la intención que haga.

2

Sí, podemos ajustar esta advertencia para advertir solo cuando el sombreado sea peligroso. Por ejemplo no de sombra para

conjunto vacío (int qué) .. int lo que() const ..

pero advierten de shadowning variable local y por el ejemplo funtor anteriormente.

Para ser más exactos, advierta cuando el sombreado puede ser peligroso, cuando la intención del escritor del código puede no ser clara. En el caso de un parámetro int y una función miembro con el mismo nombre, está claro que el autor no desea que se llame al miembro cuando hace referencia al parámetro.

Me parece que esta advertencia de sombra es una buena idea, muy útil, solo necesita pensar un poco más para no advertir sobre casos perfectamente seguros y claros. Yo, por ejemplo, puedo vivir con los argumentos necesarios para tener un prefijo o algo, pero prefiero nombres limpios y simples.