1

This is the typical c code:

#include <stdio.h>


int main(int argc, char **argv)
{
    
}

**I wanted to make like this argv array. But I got error. How can I make an array like this. Here is my code:

#include <stdio.h>


int main(int argc, char **argv)
{
    char **names = {"Prite", "Ridoy", "Ridhita"};

    for (int i = 0; i < 3; i++)
    {
        printf("%s\n", names[i]);
    }
}

I got this error:

$ make pointers
pointers.c:6:21: error: incompatible pointer types initializing 'char **' with an expression of type 'char [6]' [-Werror,-Wincompatible-pointer-types]
    char **names = {"Prite", "Ridoy", "Ridhita"};
                    ^~~~~~~
fatal error: too many errors emitted, stopping now [-ferror-limit=]
2 errors generated.
make: *** [<builtin>: pointers] Error 1
Ridoy Dey
  • 49
  • 7
  • Here is the source for gcc: https://github.com/gcc-mirror/gcc/blob/master/libiberty/argv.c - you could just call buildargv() with "Prite Ridoy Ridhita" – Jerry Jeremiah May 25 '22 at 03:12
  • 1
    All you need is this: `char *names[] = {"Prite", "Ridoy", "Ridhita"};` If you want it to be `NULL`-terminated (like `argv`), then add a `NULL` to the end of the initializer list. You want `names` to be an array. Don't use the anonymous array syntax shown above, *unless* you really want `names` to be a pointer that you can modify. Note that a `char *[]` will "decay" into a `char **` when passed as a function argument (among other things). – Tom Karzes May 25 '22 at 03:18
  • I tried it what you have told but I there is a question came in mind that "char *names[]" is working but "char **names" is not but the case of argv is working. – Ridoy Dey May 25 '22 at 03:26
  • @RidoyDey `argv` works because when `main` is called, an array is created to hold the pointers to the arguments. That array effectively has type `char *[]`. But when passed to `main`, it "decays" to type `char **` (just as an `int []` array is passed as `int *`). In fact, in your declaration of `main`, you can use `int main(int argc, char *argv[])` and it will work the same as if you had used `char **argv`. – Tom Karzes May 25 '22 at 03:42

1 Answers1

2

Because a char** is a pointer to a char* (string), and not an array of char*.

It may sound confusing since char* looks the same as char[], so char** should be the same as char[][], right? Actually, no.

See: What is the difference between char array and char pointer in C?

Internally they are treated as different types. In this example, char** is a pointer to a string literal and not an array of string literals.

The correct line would be

char *names[] = {"Prite", "Ridoy", "Ridhita"};
Willian
  • 31
  • 1
  • 6
  • 2
    These are string literals, so ideally you should have array of pointers to _const_ char. – hyde May 25 '22 at 03:58
  • @hyde, yes but see [the rationale for `char*[]` in the Posix standard](https://pubs.opengroup.org/onlinepubs/9699919799/functions/exec.html#tag_16_111_08). (Look for the paragraph which starts "The statement about argv[] and envp[] being constants...") – rici May 25 '22 at 20:04