0

I'm working on creating a basic shell in C, running into issues when compiling with gcc:

This is the warning from my IDE:

[query] incompatible function pointer types initializing 'const void (*)(char **)' with an expression of type 'void (*)(char **)' [-Wincompatible-function-pointer-types]

This is the error I'm getting when attempting make a pull request with a json test file set up:

 grsh.c:28:48: error: initialization from incompatible pointer type [-Werror=incompatible-pointer-types]

   const void (*command_functions[]) (char **) = {&exit_shell, &change_directory, &set_path};
                                                  ^
  grsh.c:28:48: note: (near initialization for 'command_functions[0]')
  grsh.c:28:61: error: initialization from incompatible pointer type [-Werror=incompatible-pointer-types]
   const void (*command_functions[]) (char **) = {&exit_shell, &change_directory, &set_path};

Particular line of code in question:

const void (*command_functions[]) (char **) = {&exit_shell, &cd, &set_path};

I'll be 100%, not exactly sure what the issue here is. The program compiles and runs within Repl.it when running a normal compile command, but runs into issues when attempting to compile with -Werror and -Wall

Would love to get some feedback on how to properly initialize an array of pointers with type char.

Soup
  • 23
  • 4
  • Where and how is `exit_shell` declared? – dxiv Nov 15 '20 at 00:24
  • Please [edit] your question to show more context of your code. Preferably a proper [mcve]. – Some programmer dude Nov 15 '20 at 00:24
  • You do not need `&` to take the addresses of the functions; `… = { exit_shell, change_directory, set_path };` will work just as well. A function designator is automatically converted to the address of its function except when used with `sizeof` or `&`. (Since the designator is converted to an address, `*exit_shell` takes the address and attempts to make it the function again, but that is automatically converted to the address. So you can write `***********exit_shell`, and it will still be the address. For example, you can call the sine routine as `(*************sin)(x)`.) – Eric Postpischil Nov 15 '20 at 01:01

1 Answers1

2
const void (*command_functions[]) (char **) = { /*...*/ };

The posted code copied above declares command_functions as an array of pointers to functions returning const void (which is legal, albeit uncommon, see for example this answer).

To declare command_functions as an array of const pointers to functions returning void use the following, instead.

void (*const command_functions[]) (char **) = { /*...*/ };
dxiv
  • 16,984
  • 2
  • 27
  • 49