¿Visual C acepta un número incorrecto de argumentos?

3 minutos de lectura

¿Por qué se compila esto en Visual Studio?

void foo(int a) {}

int main() {
    foo(1,2);
}

hay una advertencia

source_file.c(4) : warning C4020: 'foo' : too many actual parameters

pero ¿por qué no es un error como en el caso de gcc/clang?

Conozco las definiciones de funciones de estilo K&R, pero eso solo se aplicaría a foo() que tomaría un número variable de argumentos.

Las citas del estándar que permitan esto serían muy apreciadas.

  • Puede tratarlo como errores si habilita /WXque es el preferido.

    – héroehuyongtao

    26 de octubre de 2014 a las 5:15


  • En realidad no estoy usando VS. Recibí el código de un estudiante que pudo compilarlo con VS pero recibí errores de gcc y clang. Lanzar un error parece ser lo único razonable que puedo hacer, así que estoy tratando de entender qué está haciendo VS allí. ¿Dónde está el 2 ¿ir?

    – señoras

    26 de octubre de 2014 a las 5:17

  • Para tu información: VS2013 tratará esto como errores del compilador: error C2660: 'foo' : function does not take 2 arguments.

    – héroehuyongtao

    26 de octubre de 2014 a las 5:19


  • El estándar no define “error del compilador”. Simplemente requiere “diagnósticos”. Un diagnóstico puede ser una advertencia o un error; la norma no distingue entre ellos. El estándar tampoco requiere que un compilador rechace un programa que genera un diagnóstico.

    –Raymond Chen

    26 de octubre de 2014 a las 5:25

  • @RaymondChen Gracias, no lo sabía por completo.

    – señoras

    26 de octubre de 2014 a las 5:28

¿Visual C acepta un numero incorrecto de argumentos
codenheim

Esto no es solo MSVC.

GCC lo acepta, si la definición de su función está debajo del sitio de la llamada y no hay un prototipo. C siempre ha permitido llamar a una función no declarada. Infiere el prototipo del call-site. Así que creo que el comportamiento está relacionado con ese aspecto (aunque cuando muevo la función sobre el sitio de llamada en GCC, cambia a un error, lo que tiene sentido para C99). Sin embargo, este debería ser un comportamiento indefinido (diferente número de argumentos que parámetros).

int main()
{
   foo(1,2,3);
}

void foo(int a, int b)
{
}

f.c:6:6: warning: conflicting types for ‘foo’ [enabled by default]
 void foo(int a, int b)
      ^
f.c:3:4: note: previous implicit declaration of ‘foo’ was here
    foo(1,2,3);

encontré esto

6.7.5.3p15:

[…] Si un tipo tiene una lista de tipos de parámetros y el otro tipo está especificado por una definición de función que contiene una lista de identificadores (posiblemente vacía) [this is your situation]ambos concordarán en el número de parámetros, y el tipo de cada parámetro prototipo será compatible con el tipo que resulte de la aplicación de las promociones de argumento por defecto al tipo del identificador correspondiente. […]

…. pero este párrafo no es parte de una restricción. La violación de un “deberá” fuera de una sección de restricciones es un comportamiento indefinido, no un comportamiento que debe ser diagnosticado (4p2).

Cité esto de: http://compgroups.net/comp.lang.c/por-que-no-es-esto-un-error-en-visual-c/732881

Su experiencia puede ser diferente.

En resumen, aparentemente el único requisito es que el compilador le ladre para obtener alguna definición de ladrido. En VS 2013 se trata como un error.

En cuanto a lo que sucede con el argumento, por la misma razón por la que las listas de argumentos variables funcionan en C, el sitio de la llamada debe impulsar el argumento adicional, pero el receptor de la llamada no lo sabrá (solo adivinando aquí). Aunque funciona, no significa que sea un comportamiento definido.

¿Ha sido útil esta solución?

Esta web utiliza cookies propias y de terceros para su correcto funcionamiento y para fines analíticos y para mostrarte publicidad relacionada con sus preferencias en base a un perfil elaborado a partir de tus hábitos de navegación. Al hacer clic en el botón Aceptar, acepta el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos. Configurar y más información
Privacidad