C/GL: usando -1 come sentinella in matrice di numeri interi senza segno
-
28-10-2019 - |
Domanda
Sto passando una matrice di indici di vertice in qualche codice GL ... ogni elemento è un glusht
Voglio terminare con una sentinella in modo da evitare di dover passare faticosamente la lunghezza dell'array ogni volta accanto all'array stesso.
#define SENTINEL ( (GLushort) -1 ) // edit thanks to answers below
:
GLushort verts = {0, 0, 2, 1, 0, 0, SENTINEL};
Non posso usare 0 per terminare poiché alcuni degli elementi hanno il valore 0
Posso usare -1?
A mio avvisare ciò si avvolgerebbe al massimo intero che Glushort può rappresentare, il che sarebbe l'ideale.
Ma questo comportamento è garantito in C?
(Non riesco a trovare una costante equivalente Max_Int per questo tipo, altrimenti lo userei)
Soluzione
Se GLushort
è davvero un tipo non firmato, quindi (GLushort)-1
è il valore massimo per GLushort
. Lo standard C lo garantisce. Quindi, puoi usare in sicurezza -1
.
Ad esempio, C89 non aveva SIZE_MAX
macro per il valore massimo per size_t
. Potrebbe essere definito portabilmente dall'utente come #define SIZE_MAX ((size_t)-1)
.
Se questo funziona come valore sentinella nel codice dipende se (GLushort)-1
è un valore valido e non-sentinel nel codice.
Altri suggerimenti
GLushort
è un UNSIGNED_SHORT
Tipo che viene digitato unsigned short
, e quale, sebbene c non garantisce OpenGL si presume come un valore con un intervallo di 2^16-1 (capitolo 4.3 della specifica). Praticamente su ogni architettura tradizionale, anche questa ipotesi un po 'pericolosa è vera (non sono a conoscenza di uno dove unsigned short
ha una dimensione diversa).
Come tale, tu Potere Usa -1, ma è imbarazzante perché avrai molti cast e se dimentichi un cast, ad esempio in un if()
dichiarazione, puoi esserlo fortunato e ottenere un avvertimento del compilatore sul "confronto non può mai essere vero", oppure puoi esserlo sfortunato E il compilatore ottimizzerà silenziosamente il ramo, dopo di che trascorri giorni a cercare il motivo per cui il tuo codice apparentemente perfetto esegue sbagliato. O peggio ancora, tutto funziona bene nelle build di debug e solo bombe nelle build di rilascio.
Pertanto, usando 0xffff
Come ha consigliato JV42 è molto preferibile, evita questa trappola.
Creerei una costante di valore globale:
const GLushort GLushort_SENTINEL = (GLushort)(-1);
Penso che questo sia perfettamente elegante fintanto che i numeri interi firmati sono rappresentati usando il complemento di 2.
Non ricordo se questo è garantito dallo standard C, ma è praticamente garantito per la maggior parte delle CPU (nella mia esperienza).Modificare: Apparently questo è garantito dallo standard C ....
Se vuoi una costante denominata, non dovresti usare un const
variabile qualificata come proposto in un'altra risposta. Non sono davvero gli stessi. Usa una macro (come hanno detto altri) o una costante di tipo enumerazione:
enum { GLushort_SENTINEL = -1; };
Lo standard garantisce che questo è sempre un int
(Davvero un altro nome della costante -1
) e che si tradurrà sempre nel valore massimo del tuo tipo non firmato.
Modificare: o potresti averlo
enum { GLushort_SENTINEL = (GLushort)-1; };
Se temo che su alcune architetture GLushort
potrebbe essere più stretto di unsigned int
.