C/GL: Использование -1 в качестве Sentinel на массиве неподписанных целых чисел.

StackOverflow https://stackoverflow.com/questions/6356703

Вопрос

Я передаю массив индексов вершины в некотором коде GL ... каждый элемент - глюшера

Я хочу прекратить ссором, чтобы избежать трудолюбивого прохождения длины массива каждый раз вместе с самим массивом.

#define SENTINEL ( (GLushort) -1 ) // edit thanks to answers below
:
GLushort verts = {0, 0, 2, 1, 0, 0, SENTINEL};

Я не могу использовать 0 для прекращения, так как некоторые элементы имеют значение 0

Могу я использовать -1?

Насколько я понимаю, это может представить максимальное целое число, что будет идеально.

Но гарантировано ли это поведение в C?

(Я не могу найти эквивалентную константу max_int для этого типа, иначе я бы это использовал)

Это было полезно?

Решение

Если GLushort это действительно беспигнутый тип, тогда (GLushort)-1 максимальное значение для GLushort. Стандарт C гарантирует, что. Анкет Итак, вы можете безопасно использовать -1.

Например, у C89 не было SIZE_MAX макрос для максимального значения для size_t. Анкет Пользователь может быть портильно определен как #define SIZE_MAX ((size_t)-1).

Работает ли это в качестве значения страдания в вашем коде, зависит от того, (GLushort)-1 является достоверным, несениновым значением в вашем коде.

Другие советы

GLushort является UNSIGNED_SHORT тип, который напечатан на unsigned short, и что, хотя и не гарантирует Это, OpenGL предполагает как значение с диапазоном 2^16-1 (глава 4.3 спецификации). На практически каждой основной архитектуре это несколько опасное предположение также верно (я не знаю, где там, где unsigned short имеет другой размер).

Как таковой, вы Можно Используйте -1, но это неловко, потому что у вас будет много актеров, и если вы забудете актерский состав, например, в if() утверждение, вы можете быть счастливый и получить предупреждение компилятора о «сравнении никогда не может быть правдой», или вы можете быть несчастливый И компилятор молча оптимизирует ветвь, после чего вы проводите дни на поиски причины, по которой ваш, казалось бы, идеальный код выполняется неправильно. Или, что еще хуже, все работает нормально в сборке отладки, и только бомбы в сборке выпуска.

Поэтому использование 0xffff Как сообщил JV42, очень предпочтительнее, он избегает этой ловушки Alltogether.

Я бы создал глобальную постоянную ценность:

const GLushort GLushort_SENTINEL = (GLushort)(-1);

Я думаю, что это совершенно элегантно, если подписанные целые числа представлены с использованием комплемента 2.

Я не помню, гарантировано ли это стандартом C, но это практически гарантируется для большинства процессоров (по моему опыту).Редактировать: Попад. Это является гарантированно стандартом C ....

Если вы хотите именованную константу, вы не должны использовать const квалифицированная переменная, как предложено в другом ответе. Они действительно не такие. Используйте либо макрос (как сказали другие), либо константу типа перечисления:

enum { GLushort_SENTINEL = -1; };

Стандарт гарантирует, что это всегда int (Действительно другое имя постоянной -1) и что это всегда будет переходить в максимальное значение вашего типа без знака.

Редактировать: Или вы можете иметь это

enum { GLushort_SENTINEL = (GLushort)-1; };

Если вы боитесь этого на некоторых архитектурах GLushort может быть более узким, чем unsigned int.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top