¿Cuáles son las promociones de tipo automáticas de los argumentos de función variádica?

3 minutos de lectura

Considere el siguiente fragmento de código:

#include <stdio.h>
#include <stdarg.h>

void display(int num, ...) {
    char c;
    int j;
    va_list ptr;
    va_start(ptr,num);
    for (j= 1; j <= num; j++){
        c = va_arg(ptr, char);
        printf("%c", c);

    }
    va_end(ptr);
}

int main() {
    display(4, 'A', 'a', 'b', 'c');
    return 0;
}

El programa da un error de tiempo de ejecución porque vararg promueve automáticamente char a int, y debería haber usado int en este caso.

Cuáles son todos los tipos permitidos cuando uso vararg, cómo saber qué tipo usar y evitar tales errores de tiempo de ejecución.

  • Jeje, GCC dice, “advertencia: ‘char’ se promociona a ‘int’ cuando pasa por ‘…'”. Agradable.

    – KerrekSB

    16 de agosto de 2011 a las 20:55

  • En display(4, 'A', 'a', 'b', 'c'); hay 5 ints; no 1 int y 4 chars como pareces creer 🙂

    – pmg

    16 de agosto de 2011 a las 20:57

  • @Kerrek: dice que para la expresión va_arg(ptr, char)no la llamada a la display función — donde no hay chars 🙂

    – pmg

    16 de agosto de 2011 a las 21:02

  • @pmg: Ah, de hecho, ese es uno de los cambios de C a C ++: en C, los literales de caracteres son números enteros … Nunca supe que no podía usar caracteres de forma variable. wchar_t tampoco funciona, y tampoco char16_t o char32_t (todos son ascendidos a unsigned int).

    – KerrekSB

    16 de agosto de 2011 a las 21:05


  • Esto probablemente depende de la longitud de palabra del compilador/máquina. Incluso podría redefinir va_arg para tener esto en cuenta.

    – Quentin Reino Unido

    16 de agosto de 2011 a las 21:09

otro caso que los demás olvidaron mencionar son los tipos de puntero, crítico es NULL En particular. Dado que esto podría expandirse a 0 o (void*)0 (o algunas otras cosas raras) no sabrá si el compilador pone un int o un void* en la lista. Dado que estos pueden tener un ancho diferente, esto puede provocar errores molestos.

  • Sí, esa es siempre una fuente sutil de errores. GCC es agradable y se expande NULL para __nullptr en lugar de 0, por lo que no se encontrará con ese error con GCC, pero otros compiladores no son tan buenos. El estándar C solo requiere que NULL expanda a una “constante de puntero nulo definida por la implementación”, que es “una expresión constante entera con el valor 0, o una expresión de este tipo convertida al tipo void*.

    – Adam Rosenfield

    16 de agosto de 2011 a las 23:02

¿Cuales son las promociones de tipo automaticas de los argumentos
R.. GitHub DEJAR DE AYUDAR A ICE

Puede utilizar cualquier tipo estándar con va_arg excepto char, signed char, unsigned char, short, unsigned short, _Booly float. Es posible que una implementación defina tipos adicionales no estándar que también tengan un rango de conversión de enteros inferior a into tipos de coma flotante pequeños no estándar, pero no necesitaría conocerlos a menos que tenga la intención de usarlos, por lo que, para fines prácticos, la lista que di está completa.

¿Cuales son las promociones de tipo automaticas de los argumentos
Alaska

Al usar va_arg el char es ascendido a int. Hay otros tipos (la lista proporcionada por @R..) que se promocionan.

así que para leerlo como un char tienes que hacer typecast.

como: c = (char) va_arg(ap, int);

para ver el ejemplo completo, consulte:

http://en.cppreference.com/w/cpp/language/variadic_arguments

  • Muchas gracias, corregido los errores y actualizado a un enlace mejor.

    – Ak

    23 de febrero de 2018 a las 7:46

¿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