S1ippery
S1ippery

Reputation: 65

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.

Upvotes: 5

Views: 1185

Answers (2)

Jabberwocky
Jabberwocky

Reputation: 50831

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.

Upvotes: 2

Serge Ballesta
Serge Ballesta

Reputation: 149095

I assume that either you have declared you functions before using them or you compiler implicitely declared them as (C default) :

int start_simulation();
...

meaning start_simulation should be defined elsewhere as a function taking any parameters and returning an int.

But this should give you at least some warnings, because either the definition is different from the declaration, or the declaration of functions to not match the declaration of command for the second element of a commandstruct (in const commandStruct commands[] = ...)

For the fact that it compiles and runs fine, the cdecl way of passing parameters is as follow :

  • parameters are pushed to stack in opposite order
  • the callee is called (return address of caller is pushed to the stack)
  • callee can get its parameters starting at stack pointer + size of the return address but never removes them from the stack
  • callee returns
  • caller removes the parameters that it pushed to the stack (it knows them)

That means that you can always add unused parameters, provided the compiler is tolerant enough to compile an incorrect call, or the function was declared with an empty parameter list.

Upvotes: 1

Related Questions