Pointer to array of unspecified size “(*p)[]” illegal in C++ but legal in C

前端 未结 2 1600
滥情空心
滥情空心 2020-11-30 07:28

I just found out that this is illegal in C++ (but legal in C):

#include 
#include 
#define ARRAY_LENGTH(A) (sizeof(A) / sizeof         


        
相关标签:
2条回答
  • 2020-11-30 07:43

    C++ doesn't have C's notion of "compatible type". In C, this is a perfectly valid redeclaration of a variable:

    extern int (*a)[];
    extern int (*a)[3];
    

    In C, this is a perfectly valid redeclaration of the same function:

    extern void f();
    extern void f(int);
    

    In C, this is implementation-specific, but typically a valid redeclaration of the same variable:

    enum E { A, B, C };
    extern enum E a;
    extern unsigned int a;
    

    C++ doesn't have any of that. In C++, types are either the same, or are different, and if they are different, then there is very little concern in how different they are.

    Similarly,

    int main() {
      const char array[] = "Hello";
      const char (*pointer)[] = &array;
    }
    

    is valid in C, but invalid in C++: array, despite the [], is declared as an array of length 6. pointer is declared as a pointer to an array of unspecified length, which is a different type. There is no implicit conversion from const char (*)[6] to const char (*)[].

    Because of that, functions taking pointers to arrays of unspecified length are pretty much useless in C++, and almost certainly a mistake on the part of the programmer. If you start from a concrete array instance, you almost always have the size already, so you cannot take its address in order to pass it to your function, because you would have a type mismatch.

    And there is no need for pointers to arrays of unspecified length in your example either: the normal way to write that in C, which happens to also be valid in C++, is

    int accumulate(int n, int *array)
    {
        int i;
        int sum = 0;
        for (i = 0; i < n; ++i) {
            sum += array[i];
        }
        return sum;
    }
    

    to be called as accumulate(ARRAY_LENGTH(a), a).

    0 讨论(0)
  • 2020-11-30 08:04

    Dan Saks wrote about this in 1995, during the lead up to C++ standardisation:

    The committees decided that functions such as this, that accept a pointer or reference to an array with unknown bound, complicate declaration matching and overload resolution rules in C++. The committees agreed that, since such functions have little utility and are fairly uncommon, it would be simplest to just ban them. Hence, the C++ draft now states:

    If the type of a parameter includes a type of the form pointer to array of unknown bound of T or reference to array of unknown bound of T, the program is ill-formed.

    0 讨论(0)
提交回复
热议问题