Buongiorno, non sono riuscita a trovare su internet la risposta al mio quesito
Avendo una serie di array di INT ma con lunghezze diverse e contenuti diversi, è possibile creare una funzione che restituisca il numero di 'item' di ogni array?
So che si può fare
sizeof(array)/sizeof(int)
E mi funziona sul singolo array, ma se lo uso nel 'corpo'della funzione, mi risulta sempre 1!
Sapete come mai?
In C o C++ non è possibile farlo, è una precisa caratteristica del linguaggio
Per un puntatore, invece, allocato con malloc(), su arduino potresti "guardare" due byte "prima" del puntatore, li è conservata la dimensione allocata, in byte
Però così non riesci a distinguere tra 0 ed 1 elemento, non ho ancora chiaro perchè
Comunque assolutamente non funziona ne con array ne con puntatori non allocati
@Standardoil: perona, ma se ben ricordo si è sempre fatto:
dato un array A di qualsiasi tipo il numero degli elementi è ritornato da ( sizeof (A) / sizeof(A[0]) ), mentre sizeof(A) ritorna l'occupazione totale in byte
... dove è il problema esattamente? ... che non ho mica capito
Il Kernighan & Ritchie, a pag. 181 riporta:
A.7.4.8 Sizeof Operator
The sizeof operator yields the number of bytes required to store an object of the type of its
operand. The operand is either an expression, which is not evaluated, or a parenthesized type
name. When sizeof is applied to a char, the result is 1; when applied to an array, the result is the total number of bytes in the array. When applied to a structure or union, the result is the number of bytes in the object, including any padding required to make the object tile an array: the size of an array of n elements is n times the size of one element. The operator may not be applied to an operand of function type, or of incomplete type, or to a bit-field. The result is an unsigned integral constant; the particular type is implementation-defined. The standard header <stddef.h> (See appendix B) defines this type as size_t.
Come ti hanno già detto un array passato come argomento di funzione decade in puntatore che è grande 2 byte su AVR. sizeof lavora nel momento della compilazione e non a runtime. In C non conosco soluzione che passare oltre all'array la dimensione, mentre in C++ grazie ai template è possibile ricavare la dimensione di un array. Ma nella realtà la funzione riceve il puntatore e la dimensione. La tua funzione dovrà usare i template. Nell'esempio seguente la funzione che ha come argomento un array si chiama myFunc() e il prototipo è il seguente:
template <class T, size_t N>
void myFunc(const T (&array)[N]) {
// qui:
// N è il numero di elementi
// array è l'array che decade in puntatore
// misteriosamente funziona anche sizeof qui dentro, infatti
Serial.println(sizeof(array));
// stampa la lunghezza in byte
}
Di seguito la funzione completa da chiamare nel setup().
Non ho incontrato una call a sizeof. Se hai un disassemblato che mi mostra una chiamata a sizeof allora viene risolto anche a runtime, ma per adesso per me viene risolto nel momento della compilazione.
sizeof is always computed at compile time in C89. Since C99 and variable length arrays, it is computed at run time when a variable length array is part of the expression in the sizeof operand.
No no, non mi bastano le specifiche voglio vedere la funzione sizeof() nella libreria o se built-int nel codice del compilatore.
Se c'è mi dite dove si trova.
Ora non sono passati anni da quando spulciavo i sorgenti di compilatore e librerie, ricordo che strlen è sia una funzione quindi c'è la chiamata a funzione che la risoluzione statica nel momento della compilazione. Ovviamente ho dedotto che è il compilatore che decide se fare una chiamata a funzione o risolverlo staticamente. Per sizeof non ho mai trovato una chiamata a funzione per cui ho dedotto che viene risolto durante la compilazione.
Ripeto se avete info, link ecc postateli. Un tempo c'era un bel repo git sulle librerie standard C++, quindi sia gli header che l'implementazione qualora si trovasse in file .cpp. Ora non riesco più a trovarlo.
@gpb01
In quel documento io non vedo specificato la differenza tra run-time e compile-time, poi comunque lo leggo meglio.
Se non è una funzione allora viene generato codice asm specifico per architettura per cui ogni volta che il compilatore incontra l'uso dell'operatore genera codice asm. Se questo non è compile-time non so più la differenza allora.
Prova a leggere QUI ... scorrendo verso il basso, verso metà pagina, trovi un punto titolato "Case 2: Runtime behaviour" dove ti da i dettagli ...
From the above output it is very clear that the sizeof() operator is evaluated at runtime. We can observe the equivalent assembly code generated by the compiler as shown in Figure 6.
Also, note the difference between the assembly code in Figures 4 and 6.
Grazie per il link, purtroppo non si vede bene il codice assembler generato. Comunque se sizeof non è anche una funzione per come accade per strlen non è cambiato nulla rispetto a quanto sapevo già. Era questo che mi premeva sapere.
Da sempre c'è la diatriba di cosa vuole dire run-time e compile-time.
Io faccio parte di quelli che considerano run-time quando esiste una funzione e quindi una call asm. Tutto il resto è compile-time. Tuttavia la cosa sarebbe da approfondire ma il disassemblato di wokwi è confuso, il problema non è wokwi ma -flto Os cioè le ottimizzazione del compilatore.
@aurelias
Se le nostre discussioni ti hanno confuso le idee scusaci e che alle volte diciamo la stessa cosa e non ci capiamo.