C/GL: Verwenden Sie -1 als Sentinel auf Array von nicht signierten Ganzzahlen
-
28-10-2019 - |
Frage
Ich übertrage eine Reihe von Scheitelpunktindizes in einem GL -Code ... Jedes Element ist ein Glühenort
Ich möchte mit einem Sentinel enden, um nicht jedes Mal die Array -Länge neben dem Array selbst mühsam passieren zu müssen.
#define SENTINEL ( (GLushort) -1 ) // edit thanks to answers below
:
GLushort verts = {0, 0, 2, 1, 0, 0, SENTINEL};
Ich kann 0 nicht verwenden, um zu enden, da einige der Elemente Wert 0 haben
Kann ich -1 verwenden?
Mein Verständnis würde dies an die maximale Ganzzahl -Glushort umwickeln, die sich darstellen kann, was ideal wäre.
Aber ist dieses Verhalten in C garantiert?
(Ich kann für diesen Typ keine max_int -äquivalente Konstante finden, sonst würde ich das verwenden)
Lösung
Wenn GLushort
ist dann in der Tat ein nicht signierter Typ, dann (GLushort)-1
ist der Höchstwert für GLushort
. Der C -Standard garantiert das. Sie können also sicher verwenden -1
.
Zum Beispiel hatte C89 nicht SIZE_MAX
Makro für den Maximalwert für size_t
. Es könnte vom Benutzer als portabel definiert werden #define SIZE_MAX ((size_t)-1)
.
Ob dies als Sentinel -Wert in Ihrem Code funktioniert (GLushort)-1
ist ein gültiger, nicht-sentineler Wert in Ihrem Code.
Andere Tipps
GLushort
ist ein UNSIGNED_SHORT
Typ, der typisiert wird unsigned short
, und was, obwohl c garantiert nicht OpenGL nimmt als Wert mit einem Bereich von 2^16-1 (Kapitel 4.3 der Spezifikation) an. Bei praktisch jede Mainstream -Architektur gilt diese etwas gefährliche Annahme auch (ich bin mir nicht bewusst, wo unsigned short
hat eine andere Größe).
Als solcher Sie kann Verwenden if()
Aussage, Sie können sein Glücklich und eine Compiler -Warnung vor "Vergleich kann niemals wahr sein", oder Sie können es sein unglücklich Und der Compiler wird den Zweig still optimieren, woraufhin Sie Tage damit verbringen, nach dem Grund zu suchen, warum Ihr scheinbar perfekter Code falsch ausgeführt wird. Oder noch schlimmer, es funktioniert alles gut in Debug -Builds und nur Bomben in Release -Builds.
Daher verwendet 0xffff
Wie JV42 beraten hat, ist es sehr bevorzugt, es vermeidet diese Fallstricks alleine.
Ich würde eine globale Wertkonstante schaffen:
const GLushort GLushort_SENTINEL = (GLushort)(-1);
Ich denke, das ist vollkommen elegant, solange signierte Ganzzahlen unter Verwendung von 2 von 2 dargestellt werden.
Ich erinnere mich nicht, ob das vom C -Standard garantiert ist, aber für die meisten CPUs (meiner Erfahrung nach) praktisch garantiert.Bearbeiten: Apparent das ist garantiert durch den C -Standard ....
Wenn Sie eine benannte Konstante möchten, sollten Sie keine verwenden const
Qualifizierte Variable wie in einer anderen Antwort vorgeschlagen. Sie sind wirklich nicht dasselbe. Verwenden Sie entweder ein Makro (wie andere gesagt) oder eine Konstante der Aufzählungstyp:
enum { GLushort_SENTINEL = -1; };
Der Standard garantiert, dass dies immer ein ist int
(Wirklich ein anderer Name der Konstanten -1
) und dass es immer in den maximalen Wert Ihres nicht signierten Typs übersetzt wird.
Bearbeiten: oder du könntest es haben
enum { GLushort_SENTINEL = (GLushort)-1; };
Wenn Sie das auf einigen Architekturen fürchten GLushort
könnte schmaler sein als unsigned int
.