Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

200
Visualizações
Argumentos de puntero de función ignorados/no necesarios

Actualmente estoy escribiendo código C para un microprocesador y me encontré con algo que no podía explicar. Implementé una interfaz de línea de comando usando punteros de función. Para hacer esto, he creado una estructura que contiene el nombre del comando, el puntero a la función que se ejecutará y también una descripción de ayuda.

 typedef void(*command)(char *); typedef struct commandStruct { char const *name; command execute; char const *help; } commandStruct; const commandStruct commands[] = { {"led", CmdLed, "Turns on or off the LED1"}, {"AT+START_SIM", start_simulation, "Starts the simulation"}, {"AT+STOP_SIM", stop_simulation, "Stops the simulation"}, {"",0,""} //End of table indicator. }; void exec_command(char *buffer) { uint16 i = 0; char *cmd = buffer; char *args; while (buffer[i]) { if(buffer[i] == '=') { buffer[i] = 0; args = buffer + i + 1; break; } i++; } uint16 cmdCount = 0; while(strcmp(commands[cmdCount].name,"")) { if(!strcmp(commands[cmdCount].name,cmd)) { commands[cmdCount].execute(args); break; } cmdCount++; } } void start_simulation(void) {run = 1;} void stop_simulation(void) {run = 0;} void CmdLed(char *args) { P1DIR |= BIT0; if(!strcmp(args,"on")) P1OUT = 1; if(!strcmp(args,"off")) P1OUT = 0; }

He incluido arriba la función exec_command que es donde se usa el puntero de función. En la parte inferior también he puesto las funciones start_simulation y stop_simulation , junto con CmdLed . Escribí CmdLed en una fecha anterior y luego volví y escribí start_simulation y stop_simulation . Había olvidado que había definido mi puntero de función tomando un (char *) como argumento. Sin embargo, me sorprendió descubrir que todo seguía compilado y funcionaba absolutamente bien. ¿Por qué es esto? Parece que cualquier argumento simplemente se 'descartó' y no se usa.

over 4 years ago · Santiago Trujillo
2 Respostas
Responde à pergunta

0

Esto no debería compilarse con compiladores modernos.

Qué pasa aquí :

start_simulation se llamará con un argumento char* , pero como start_simulation no tiene argumento, el argumento simplemente se ignora (o se "descarga" mientras escribe).

Recuerde, en la función C, los argumentos se colocan en la pila y la persona que llama limpia la pila después de la llamada. Así que si llamas a una función sin argumento fingiendo que tiene argumento(s), entonces

  • la persona que llama empuja los argumentos a la pila
  • la función sin argumentos es llamada por la persona que llama
  • la función hace su trabajo ignorando los argumentos en la pila
  • las funciones vuelven a la persona que llama
  • la persona que llama limpia la pila

Eche también un vistazo a esta pregunta SO .

over 4 years ago · Santiago Trujillo Relatório

0

Supongo que ha declarado sus funciones antes de usarlas o su compilador las declaró implícitamente como (C predeterminado):

 int start_simulation(); ...

lo que significa que start_simulation debe definirse en otro lugar como una función que toma cualquier parámetro y devuelve un int.

Pero esto debería darle al menos algunas advertencias, porque la definición es diferente de la declaración, o la declaración de funciones no coincide con la declaración de comando para el segundo elemento de una estructura de comando (en const commandStruct commands[] = ... )

Por el hecho de que compila y funciona bien, la forma cdecl de pasar parámetros es la siguiente:

  • los parámetros se empujan para apilarse en orden opuesto
  • se llama a la persona que llama (la dirección de retorno de la persona que llama se empuja a la pila)
  • El receptor de la llamada puede obtener sus parámetros a partir del puntero de la pila + el tamaño de la dirección de retorno, pero nunca los elimina de la pila.
  • la persona que llama regresa
  • la persona que llama elimina los parámetros que empujó a la pila (los conoce)

Eso significa que siempre puede agregar parámetros no utilizados, siempre que el compilador sea lo suficientemente tolerante para compilar una llamada incorrecta, o la función se declaró con una lista de parámetros vacía.

over 4 years ago · Santiago Trujillo Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda