Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Function pointer arguments ignored/not needed

I'm currently writing C code for a microprocessor and I came across something I couldn't explain. I have implemented a command line interface using function pointers. To do this I have made a struct holding the name of the command, the pointer to the function to be run and also a help description.

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;
}

I have included above the function exec_command which is where the function pointer is used. At the bottom I have also put the start_simulation and stop_simulation functions, along with CmdLed. I wrote CmdLed at an earlier date and then came back and wrote start_simulation and stop_simulation. I had forgotten that I had defined my function pointer as taking a (char *) as an argument. However, I was surprised to find that everything still compiled and ran absolutely fine. Why is this? It seems that any arguments are just 'dumped' and not used.

like image 320
S1ippery Avatar asked Oct 20 '22 06:10

S1ippery


1 Answers

This should not compile with modern compilers.

What happens here :

start_simulation will be called with a char* argument, but as start_simulation has no argument the argument is simply ignored (or "dumped" as you write).

Remember, in C function arguments are pushed onto the stack and the caller cleans up the stack after the call. So if you call a function with no argument pretending it has argument(s), then

  • the caller pushes the argument(s) onto the stack
  • the argumentless function is called by the caller
  • the function does it's business ignoring the argument(s) on the stack
  • the functions returns to the caller
  • the caller cleans up the stack

Have also a look at this SO question.

like image 96
Jabberwocky Avatar answered Oct 31 '22 10:10

Jabberwocky