Sto attraversando un aumento di interesse nel sistema di tipi variati di C99. Questa domanda è stata ispirata da this one.Compatibilità dei tipi modificati e le relative implicazioni sulla sicurezza
Controllando il codice da questa domanda, ho scoperto qualcosa di interessante. Considerate questo codice:
int myFunc(int, int, int, int[][100]);
int myFunc(int a, int b, int c, int d[][200]) {
/* Some code here... */
}
Questo ovviamente non lo farà (e non) la compilazione. Tuttavia, questo codice:
int myFunc(int, int, int, int[][100]);
int myFunc(int a, int b, int c, int d[][c]) {
/* Some code here... */
}
compila senza nemmeno un avviso (su gcc).
Ciò sembra implicare che un tipo di matrice variabilmente modificato sia compatibile con qualsiasi tipo di matrice non variabile in modo variabile!
Ma non è tutto. Ci si aspetterebbe che un tipo variabilmente modificato si preoccupasse almeno di quale variabile è usata per impostare le sue dimensioni. Ma non sembra farlo!
int myFunc(int, int b, int, int[][b]);
int myFunc(int a, int b, int c, int d[][c]) {
return 0;
}
Compilare anche senza errori.
Quindi, la mia domanda è: è questo comportamento standard corretto?
Inoltre, se un tipo di matrice variabilmente modificato sarebbe realmente compatibile con qualsiasi array che abbia le stesse dimensioni, non significherebbe problemi di sicurezza brutti? Ad esempio, prendere in considerazione il seguente codice:
int myFunc(int a, int b, int c, int d[][c]) {
printf("%d\n", sizeof(*d)/sizeof((*d)[0]));
return 0;
}
int main(){
int arr[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
myFunc(0, 0, 100, &arr);
return 0;
}
Compilazioni e uscite 100, nessun errore o avviso, nulla. Per come la vedo io, ciò significa facile scrittura di array out-of-bounds anche se si sta controllando rigorosamente la dimensione dell'array via sizeof
, non facendo un singolo cast e si hanno anche tutti gli avvisi attivati! O mi sta sfuggendo qualcosa?
Se non lo hai già fatto, prova ad aggiungere -std = c99 -pedantic-errors alla tua riga di compilazione gcc e vedere se questo fa alcuna differenza. – jschultz410
@ jschultz410: buona idea, ma no-non fa alcuna differenza = ( – Mints97
Ci sono molti casi in cui sarebbe impossibile per il compilatore dedurre staticamente il valore di c (ad esempio, c è input da stdin). sarebbe spesso impossibile eseguire qualsiasi tipo di controllo statico di tipo significativo sui parametri di tale definizione di funzione.Sembra che se si esegue questa operazione, il compilatore sta dicendo "OK, ti permetterò di passare tutto ciò che vuoi come d, quindi per quanto il suo tipo sia una matrice di indici doppiamente indicizzata. Buona fortuna! " – jschultz410