でCにおける違法++が、法的:ポインタ「(* P)[]」私は、これは(Cではなく、法的な)C++で違法であることが判明C
#include <stdio.h>
#include <stdlib.h>
#define ARRAY_LENGTH(A) (sizeof(A)/sizeof(A[0]))
int accumulate(int n, const int (*array)[])
{
int i;
int sum = 0;
for (i = 0; i < n; ++i) {
sum += (*array)[i];
}
return sum;
}
int main(void)
{
int a[] = {3, 4, 2, 4, 6, 1, -40, 23, 35};
printf("%d\n", accumulate(ARRAY_LENGTH(a), &a));
return 0;
}
それはコンパイルgcc -std=c89 -pedantic
を使用しても問題なく、g++
を使用してコンパイルできません。私はこれらのエラーメッセージを取得g++
を使用して、それをコンパイルしようとすると:
main.cpp:5:37: error: parameter 'array' includes pointer to array of unknown bound 'int []'
int accumulate(int n, int (*array)[])
^
main.cpp: In function 'int main()':
main.cpp:18:50: error: cannot convert 'int (*)[9]' to 'int (*)[]' for argument '2' to 'int accumulate(int, int (*)[])'
printf("%d\n", accumulate(ARRAY_LENGTH(a), &a));
私は長い間私のCコードでこれを使用していると私はそれがC++で違法だったとは思いもしませんでした。私にとっては、これは、関数が手作業で知られていない配列の大きさをとることを文書化する便利な方法のようです。
なぜこれが正当なCですが、無効なC++であるかを知りたいのですが。私はまた、C++委員会がそれを取り除くことを決定した(そして、Cとのこの互換性を破る)ことが何であったのだろうかと思います。
なぜこの法的Cコードが違法なC++コードですか?
C++の分割時に存在していたCのバージョンに、不特定のサイズの配列がありましたか?当時はそれらをポインタとして宣言しなければならず、 '[] 'を使うことができるのは後で追加されたものだと思います。 – Barmar
C++はC89から分割されていて、この例は 'gcc -std = c89 -pedantic'を使っても問題なくコンパイルできますので、後で追加したとは思いません。 – wefwefa3
'n 'をテンプレートパラメータ('テンプレート ')に変換し、それを配列型(' int(* array)[n] ')で使用するとコードが動作するはずです。また、配列へのポインタの代わりに配列への参照を使用することも可能です(そして大抵の場合はもっと簡単です):int(&array)[n] '。それから 'accumulate(&a)'を呼び出して、コンパイラに 'n'を推測させてください! ;) –
leemes