Pregunta ¿Por qué el código de C ++ no tiene un nombre de argumento formal en una compilación de definición de función sin advertencias?


Al comenzar con algunos códigos MFC generados por VS2005, noté que se superó un método con algo como esto:

void OnDraw(CDC* /*pDC*/)
{
    ...
    // TODO: Add your code here
}

Así que, por supuesto, tan pronto como agregué algo me di cuenta de que necesitaba des-comentar el argumento formal de pDC para compilar, pero estoy confundido sobre cómo / por qué una función de C ++ puede compilar (sin advertencias) cuando la formal argumento solo tiene un tipo y no un nombre:

void foo(int)
{
    int x = 3;
}
int main()
{
    foo(5);
    return 0;
}

¿No debería esto generar al menos una advertencia (con -Wall o / W4)? Parece que no. ¿Me estoy perdiendo de algo? ¿Hay algún caso donde esto sea útil o es solo porque el compilador no puede distinguir entre una declaración de función (solo los tipos requeridos) y una definición (completamente especificada) hasta después de que la línea haya sido procesada?


35
2018-02-23 16:08


origen


Respuestas:


Porque a veces tiene un parámetro requerido por una interfaz pero la función no lo usa. Tal vez el parámetro ya no sea necesario, solo es necesario en otras funciones que deben usar la misma firma (especialmente para que se puedan llamar a través de punteros) o la funcionalidad aún no se ha implementado. Tener parámetros que no se usan puede ser particularmente común en el código generado o de infraestructura por esta razón (y esa es probablemente la razón por la cual el código generado por MFC tiene el nombre comentado).

En cuanto a por qué no hay ninguna advertencia, creo que es porque si esto es un problema es algo subjetivo y otras personas (particularmente los implementadores de compiladores) no lo ven como un problema. Una vez que realmente vas a utilizar el parámetro, conseguirás que el compilador se queje si olvidas descomentar el nombre para que el compilador se queje solo cuando realmente lo necesites (la versión del compilador del ágil YAGNI: "You Aren") t Gonna Neet It "filosofía".

Por lo general, parece que ocurre lo contrario cuando se activan las advertencias (los parámetros nombrados que no se usan generan advertencias). De nuevo, esa es probablemente la razón por la cual la función generada tiene el nombre comentado.


43
2018-02-23 16:10



La razón más común que he visto es suprimir las advertencias de variables no utilizadas que el compilador arrojará:

#include <iostream>

void foo(int source)
{
  std::cout << "foo()" << std::endl;
}

int main()
{
  foo(5);
  return 0;
}

gcc dice: main.cc:3: warning: unused parameter 'source'

Hay dos formas comunes de deshacerse de la advertencia: comente el nombre de la variable o elimínelo por completo:

void foo(int /*source*/)
{
  std::cout << "foo()" << std::endl;
}

versus

void foo(int)
{
  std::cout << "foo()" << std::endl;
}

Recomiendo encarecidamente comentar sobre la eliminación. De lo contrario, los programadores de mantenimiento tendrán que averiguar qué representa ese parámetro de alguna otra manera.

Qt (y probablemente otros marcos) proporciona una macro que suprime la advertencia sin necesidad de comentar o eliminar el nombre de la variable: Q_UNUSED(<variable>):

void foo(int source)
{
  Q_UNUSED(source); // Removed in version 4.2 due to locusts
  std::cout << "foo()" << std::endl;
}

Esto le permite llamar en el cuerpo de la función que la variable no se usa, y le da un gran lugar para documentar por qué no se usa


15
2018-02-23 16:09



Calado estándar C ++ 11 N3337

http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3337.pdf dice que es legal en 8.4.1 / 6  "Definiciones de funciones> En general":

Nota: los parámetros no utilizados no necesitan ser nombrados. Por ejemplo,

void print(int a, int) {
    std::printf("a = %d\n",a);
}

Más precisamente, 8.4.1 / 1 dice que la gramática para las definiciones de funciones es

function-definition:
    attribute-specifier-seqopt decl-specifier-seqopt
    declarator virt-specifier-seqopt function-body

Luego, si sigues las definiciones de gramática, p. en "Resumen de Gramática del Anexo A", verá que los nombres son opcionales.


4
2017-07-01 11:10



Se compila porque el estándar de lenguaje dice específicamente que debe compilarse. No hay otra respuesta. Este es uno de los bits que hacen que C ++ sea diferente de C. En C, los nombres de los parámetros en definición de función deben estar presentes, en C ++ son opcionales.

De hecho, me pregunto por qué preguntas tu pregunta "por qué". ¿Ves algo antinatural, inusual o ilógico en este comportamiento?


2
2018-02-23 19:09