C / GL: использование -1 в качестве стража для массива целых чисел без знака - PullRequest
3 голосов
/ 15 июня 2011

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

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

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

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

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

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

Но гарантируется ли такое поведение в C?

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

Ответы [ 4 ]

5 голосов
/ 15 июня 2011

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

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

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

1 голос
/ 15 июня 2011

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

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

Следовательно, использование 0xffff, как советовал jv42, гораздо предпочтительнее, оно полностью избегает этой ловушки.

1 голос
/ 15 июня 2011

Я бы создал глобальную константу значения:

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

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

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

0 голосов
/ 15 июня 2011

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

enum { GLushort_SENTINEL = -1; };

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

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

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

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

...