1

i am trying to initialize an array of strings in c in different ways and i'm having trouble to understand how it behaves.

i'm trying to initialize the array and print it ,i have tried three ways to initialize the array

char **argv = {"foo","boo"};
char *argv[] = {"foo","boo"};
char ****argv[] = {"foo","boo"};

and then print them using

    printf("%s",argv[1]);

i expected the first and second one to run and the third to fail but the first one is giving me run time error and the other run without any problem why? and how does c compile them

6
  • 1
    For your purposes, way #2 should be the best. Please tell us more abut the "run time error" you got when you tried that. Commented Oct 30, 2019 at 16:53
  • That third one is utterly bizarre. Are you sure that's what you mean? Commented Oct 30, 2019 at 16:55
  • 1
    Note that if you plan on passing argv to a function like execv(), it needs a null pointer at the end, so it should be {"foo", "boo", NULL} Commented Oct 30, 2019 at 16:56
  • 1
    Try compiling with -Wall because these examples make clang refuse to compile due to wildly mismatched types. Commented Oct 30, 2019 at 16:57
  • 1
    char **argv = {"foo","boo"}; initializes from incompatible pointer types. char ****argv[] = {"foo","boo"}; has 3-Levels of indirection too many. char *argv[] = {"foo","boo"}; is the only correct guess... Always compile with -Wall -Wextra -pedantic as part of your compile string. Commented Oct 30, 2019 at 16:57

1 Answer 1

3

Among these declarations

char **argv = {"foo","boo"};
char *argv[] = {"foo","boo"};
char ****argv[] = {"foo","boo"};

only the second declaration is valid.

The first declaration is not valid because you may not use a list in braces with more than one expression to initialize a scalar object. And even if you will use only one string literal in braces in the first declaration nevertheless the type of the declared variable ( char ** ) and the type of the initializer ( char * ) are different and there is no implicit conversion between the types.

The third declaration is invalid because there is no implicit conversion between the type char * (the type of the string literals used as initializers) and the type char ****.

Valid declarations in C of character arrays using the presented list of initializers can be

char *argv1[] = {"foo","boo"};  
char argv2[][3] = {"foo","boo"};    
char argv3[][4] = {"foo","boo"};    

Here is a demonstrative program

#include <stdio.h>

int main(void) 
{
    char *argv1[] = {"foo","boo"};  
    char argv2[][3] = {"foo","boo"};    
    char argv3[][4] = {"foo","boo"};    


    printf( "%s, %s\n", argv1[0], argv1[1] );
    printf( "%3.3s, %3.3s\n", argv2[0], argv1[1] );
    printf( "%s, %s\n", argv3[0], argv3[1] );

    return 0;
}

Its output is

foo, boo
foo, boo
foo, boo

To make the first initialization correct you can write

char * p[] = {"foo","boo"}
char **argv = p;

Another way is to use the compound literal like

char **argv= ( char *[] ){"foo","boo"};

Here is one more demonstrative program

#include <stdio.h>

int main(void) 
{
    char **argv= ( char *[] ){"foo","boo"}; 


    printf( "%s, %s\n", argv[0], argv[1] );

    return 0;
}

Its output is

foo, boo
Sign up to request clarification or add additional context in comments.

2 Comments

so how to initialize the first one properly?
@MahmoudAbdelbary I do not understand why you need such an initialization but you can write char *p = "foo"; char **argv = &p;

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.