开发者

C/GL: Using -1 as sentinel on array of unsigned integers

I am passing an array of vertex indices in som开发者_如何学编程e GL code... each element is a GLushort

I want to terminate with a sentinel so as to avoid having to laboriously pass the array length each time alongside the array itself.

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

I cannot use 0 to terminate as some of the elements have value 0

Can I use -1?

To my understanding this would wrap to the maximum integer GLushort can represent, which would be ideal.

But is this behaviour guaranteed in C?

(I cannot find a MAX_INT equivalent constant for this type, otherwise I would be using that)


If GLushort is indeed an unsigned type, then (GLushort)-1 is the maximum value for GLushort. The C standard guarantees that. So, you can safely use -1.

For example, C89 didn't have SIZE_MAX macro for the maximum value for size_t. It could be portably defined by the user as #define SIZE_MAX ((size_t)-1).

Whether this works as a sentinel value in your code depends on whether (GLushort)-1 is a valid, non-sentinel value in your code.


GLushort is an UNSIGNED_SHORT type which is typedefed to unsigned short, and which, although C does not guarantee it, OpenGL assumes as a value with a 2^16-1 range (Chapter 4.3 of the specification). On practically every mainstream architecture, this somewhat dangerous assumption holds true, too (I'm not aware of one where unsigned short has a different size).

As such, you can use -1, but it is awkward because you will have a lot of casts and if you forget a cast for example in an if() statement, you can be lucky and get a compiler warning about "comparison can never be true", or you can be unlucky and the compiler will silently optimize the branch out, after which you spend days searching for the reason why your seemingly perfect code executes wrong. Or worse yet, it all works fine in debug builds and only bombs in release builds.

Therefore, using 0xffff as jv42 has advised is much preferrable, it avoids this pitfall alltogether.


I would create a global constant of value:

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

I think this is perfectly elegant as long as signed integers are represented using 2's complement.

I don't remember if thats guaranteed by the C standard, but it is virtually guaranteed for most CPU's (in my experience). Edit: Appparently this is guaranteed by the C standard....


If you want a named constant, you shouldn't use a const qualified variable as proposed in another answer. They are really not the same. Use either a macro (as others have said) or an enumeration type constant:

enum { GLushort_SENTINEL = -1; };

The standard guarantees that this always is an int (really another name of the constant -1) and that it always will translate into the max value of your unsigned type.

Edit: or you could have it

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

if you fear that on some architectures GLushort could be narrower than unsigned int.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜