es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Obtén la respuesta incorrecta——sobre un número incierto de variables.

Cuando ejecuté el programa a continuación en el sistema Linux, no pude obtener la respuesta esperada “9”. Pero puedo obtenerla en el sistema Windows.

¿Por qué sucede esto?


#include <stdio.h> int sum(int num, ...) { int* p = &num + 1; int res = 0; while (num--) { res += *p++; } return res; } int main() { printf("%d\n", sum(3, 2, 3, 4)); return 0; }

Lo depuré en GDB, se muestra a continuación:
imagen de descripción de la imagen

La configuración de mi sistema es la siguiente.

Versión de Linux 5.11.0-41-generic (buildd@lgw01-amd64-005) (gcc (Ubuntu 9.3.0-17ubuntu1~20.04) 9.3.0, GNU ld (GNU Binutils para Ubuntu) 2.34)</stdio.h>

Tags:  , ,

Answer

  1. Avatar for davy.ai

    El problema está relacionado con la forma en que se pasan los argumentos en los sistemas Linux y Windows. En el lenguaje C, las funciones variádicas se implementan utilizando la sintaxis de “puntos suspensivos”, que permite que una función acepte un número variable de argumentos.

    En este programa en particular, la función variádica sum toma un entero num seguido de una secuencia de enteros. La función sum utiliza aritmética de punteros para iterar sobre la secuencia de enteros y calcular su suma.

    El problema con el código es que asume que los argumentos pasados a la función sum se almacenan en ubicaciones de memoria consecutivas. Esto no está garantizado por el estándar C y puede variar entre diferentes sistemas y compiladores.

    En el sistema Windows, los argumentos resultan estar pasados en ubicaciones de memoria consecutivas, lo que permite que el programa funcione correctamente. Sin embargo, en el sistema Linux, los argumentos se pasan en un orden diferente o utilizando una disposición de memoria diferente, lo que hace que el programa se comporte incorrectamente.

    Para solucionar este problema, puedes modificar la función sum para utilizar un enfoque diferente para iterar sobre los argumentos. Una técnica común es utilizar las macros va_start, va_arg y va_end de la biblioteca stdarg.h para acceder a los argumentos variables de manera portátil y segura. Aquí tienes una implementación de ejemplo de la función sum utilizando va_list:

    #include <stdarg.h>
    
    int sum(int num, ...) {
        int res = 0;
        va_list args;
        va_start(args, num);
        for (int i = 0; i < num; i++) {
            res += va_arg(args, int);
        }
        va_end(args);
        return res;
    }
    

    Esta versión de la función sum utiliza va_list para inicializar, iterar y limpiar los argumentos variables pasados a la función. Es más robusta y debería funcionar correctamente en diferentes sistemas y compiladores.</stdarg.h>

Comments are closed.