Search code examples
carraysfunctionpointerscompound-literals

Define new function, array, struct etc inside of parameter of function call


If you had a function which took the following:

void foo(char **arr);

How can you do the following:

void foo(char* x[] = { "hello", "my", "friend" });

If this confuses you, in Java we do this by the following:

public void foo(String[] x);

foo(new String[] { "hello", "my", "friend" });

Currently, I do the following in C which I hate because it looks really ugly:

char* myArr[] = 
    { 
        "hello", "my", "friend"
    };

foo(myArr);

Solution

  • How can you do the following:

    void foo(char* x[] = { "hello", "my", "friend" });
    

    You nearly made it ... ;-)

    If doing C99 or newer use a compound literal like this:

    foo((char *[]){"hello", "my", "friend"});
    

    Mind that the called function (foo() here) has no clue how many elements the pointer array has, so you want to add a final null-pointer as sentinel:

    foo((char *[]){"hello", "my", "friend", NULL});
    

    Example:

    #include <stdio.h>
    #include <stdlib.h> /* for EXIT_xxx macros */
    
    
    void foo(char **arr)
    {
      while (arr && *arr)
      {
        printf("%s\n", *arr);
        ++arr;
      }
    }
    
    int main(void)
    {
      foo((char *[]){"hello", "my", "friend", NULL}); /* Mind the final NULL. */
    
      return EXIT_SUCCESS;
    }
    

    This will print:

    hello
    my
    friend
    

    The compound literal is valid until the scope it got defined in is left (main() here). If you want to make sure it gets removed from the stack immediately after its usage put braces around the call to foo() creating a local scope/block:

    int main(void)
    {
      {
        foo((char *[]){"hello", "my", "friend", NULL}); /* Mind the final NULL. */
      }
    
      /* The compound literal passed to foo() is already deallocated here, had been 
         removed from the stack. */
    
      ...