ho appena scoperto che questo è illegale in C++ (ma legale in C):puntatore a vettore di dimensioni non specificato "(* p) []" illegale in C++, ma legale in 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;
}
compila senza problemi usando gcc -std=c89 -pedantic
ma non riesce a compilare usando g++
. Quando provo a compilare utilizzando g++
ottengo questi messaggi di errore:
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));
Ho utilizzato questo nel mio codice C per molto tempo e non avevo idea che fosse illegale in C++. Per me questo sembra un modo utile per documentare che una funzione prende un array le cui dimensioni non sono conosciute prima della mano.
Voglio sapere perché questo è C legale ma C++ non valido. Mi chiedo anche che cosa abbia fatto decidere al comitato del C++ di portarlo via (e rompere questa compatibilità con C).
Quindi, perché questo codice C legale ma codice C++ illegale?
La versione di C esistente quando C++ è stata suddivisa ha array di dimensioni non specificate? Penso che dovessi dichiararli come indicatori in quei giorni, e poter usare '[]' fu un'aggiunta successiva. – Barmar
Il C++ è stato diviso da C89 e l'esempio si compila senza problemi usando 'gcc -std = c89 -pedantic' quindi non penso che sia stata un'aggiunta successiva. – wefwefa3
Nota che il tuo codice dovrebbe funzionare se converti 'n' in un parametro template (' template ') e lo usi nel tipo array (' int (* array) [n] '). Si noti inoltre che è persino possibile (e il più delle volte più semplice) utilizzare un riferimento all'array anziché al puntatore all'array: 'int (& array) [n]'. Quindi chiamalo con 'accumulate (& a)' e lascia che il compilatore deduca 'n' per te! ;) –
leemes