开发者

Cannot convert from 'T[N][2]' to 'T[][2]'

I have an API taking some options:

void init_api(const char* options[][2]);

I am allowed to pass a NULL pointer for no options, alternatively, an options array such as this can be passed:

const char* some_options[][2] = { {"opt1", "val1"}, 
          开发者_运维百科                        {"opt2", "val2"}, 
                                  {0,0} 
                                };

This works without problems:

...
init_api(some_options);
... or ...
init_api(NULL);
...

However, this fails to compile:

const char* my_options[][2] = NULL; // error C2440: 'initializing' : cannot convert from 'int' to 'const char *[][2]'
if(...) {
  my_options = some_options; // error C2440: '=' : cannot convert from 'const char *[4][2]' to 'const char *[][2]'
}
init_api(my_options); // no error here

What is going on here? Can someone explain this?


To declare an empty array of array of pointers to const char, you should use:

const char* my_options[][2] = {};

You need to declare a pointer to an array of pointers to const char instead. I recommend using a typedef to simplify the syntax.

typedef const char* array_of_two_cstring[2];
array_of_two_cstring* my_options = NULL;
if (...) {
    my_options = some_options;
}
init_api(my_options);

In C++ (it is herited from C), array can be implicitly converted to pointer (only once though, that is char[] is compatible with char* but char[][] is compatible with char*[] but not `char**). However, the variable cannot be reassigned. So here you need to use a pointer instead of an array.

The init_api option accepts NULL as a parameter because for the compiler, its prototype is void init_api(char const* (*)[2]) (the first array degenerated into a pointer), and NULL is a valid pointer.


The compiler must know the array size.

If you omit the size of the array (ie: using []) you need to initialize the array with the definition, in order to let the compiler count how many items that array will contain.

Moreover you are assigning a pointer (NULL) to an array: const char *x[][2] is an array of two pointers to const char.


Edit:

In C++ (as in C), arrays can decay into pointers when you use them (with three exceptions which are not interesting here).

When you pass an array to a function expecting an array, what happens is that you actually pass a pointer to the array, since the array decays; you cannot pass an array by value in C or C++.

For this reason you can pass NULL to your function; the function parameter will be NULL, and if you try to access the array within your function (options[0]) your application will crash: you'll be dereferencing an invalid pointer.

You cannot however set your array variable to NULL, since it's not a pointer, it's an array: it will only decay when you'll use it in an expression.


const char* options[][2]  

is an array of const char* pointers. You can't assign a pointer to an array.


A parameter declared as being an array of type T[N] or T[] becomes actually a parameter of type T*. Same is done for functions (a parameter declared as R(Params) becomes actually a parameter of type R(*)(Params...)).

Such transformation however is not done for other declarations. The reason it's done for function by-value parameters is that there is no way in C to actually copy an array directly (that is, to actually copy its contents) and it doesn't make sense to try and copy a function either, so such parameters are transformed in a way that conveys their purpose in a meaningful way.

So while you are initializing a pointer in the function parameter case, you are trying to initialize an array in the other case.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜