Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/iphone/37.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C/GL:使用-1作为无符号整数数组的哨兵_C_Arrays_Opengl Es 2.0_Unsigned Integer_Sentinel - Fatal编程技术网

C/GL:使用-1作为无符号整数数组的哨兵

C/GL:使用-1作为无符号整数数组的哨兵,c,arrays,opengl-es-2.0,unsigned-integer,sentinel,C,Arrays,Opengl Es 2.0,Unsigned Integer,Sentinel,我正在传递一些GL代码中的顶点索引数组。。。每个元素都是一个短元素 我希望以哨兵结束,以避免每次都要费力地沿着阵列本身传递阵列长度 #define SENTINEL ( (GLushort) -1 ) // edit thanks to answers below : GLushort verts = {0, 0, 2, 1, 0, 0, SENTINEL}; 我无法使用0终止,因为某些元素的值为0 我能用-1吗 据我所知,这将包装到GLushort可以表示的最大整数,这将是理想的 但是这种行

我正在传递一些GL代码中的顶点索引数组。。。每个元素都是一个短元素

我希望以哨兵结束,以避免每次都要费力地沿着阵列本身传递阵列长度

#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等效常量,否则我将使用该常量)

我将创建一个全局值常量:

const GLushort GLushort_SENTINEL = (GLushort)(-1);
我认为这是完美的,只要有符号整数是用2的补码表示的

我不记得C标准是否保证了这一点,但根据我的经验,大多数CPU实际上都保证了这一点。
编辑:Appparently这是由C标准保证的。

GLushort
是一种
无符号SHORT
类型,其类型定义为
无符号SHORT
,尽管C不保证,但OpenGL假定其值的范围为2^16-1(本规范第4.3章)。在几乎所有主流体系结构上,这种有点危险的假设也成立(我不知道
unsigned short
的大小不同)

因此,您可以使用-1,但这很尴尬,因为您将有很多强制转换,如果您忘记了一个强制转换,例如在
if()
语句中,您可能会幸运地得到一个关于“比较永远不可能为真”的编译器警告,或者您可能不幸运,编译器会默默地优化分支,在此之后,您将花费数天的时间寻找看似完美的代码执行错误的原因。或者更糟糕的是,它在调试版本中运行良好,只在发布版本中爆炸


因此,使用jv42建议的
0xffff
更可取,它可以避免这个陷阱。

如果
GLushort
确实是无符号类型,那么
(GLushort)-1
GLushort
的最大值。因此,您可以安全地使用
-1

例如,C89没有为
SIZE\u t
的最大值设置
SIZE\u MAX
宏。用户可以将其便携式定义为
#define SIZE_MAX((SIZE_t)-1)


这是否作为代码中的哨兵值,取决于
(GLushort)-1
在代码中是否是有效的非哨兵值。

如果需要命名常量,则不应使用另一个答案中建议的
const
限定变量。他们真的不一样。使用宏(如其他人所说)或枚举类型常量:

enum { GLushort_SENTINEL = -1; };
标准保证这始终是一个
int
(实际上是常量的另一个名称
-1
),并且它始终将转换为无符号类型的最大值

编辑:或者你可以拥有它

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

如果您担心在某些体系结构上,
GLushort
可能比
unsigned int

窄,那么即使使用不使用两个补码表示的机器,C标准也能保证它的正确性。@SCM:我想您错过了其中的类型:“const GLushort GLushort_SENTINEL=(GLushort)(.1);”
short
不是2字节的架构似乎分为三大类:旧的超互斥器、古老的计算机和DSP。然而,如果你比较
(GLushort)x==GLushort\u SENTINEL
,你会调用“未定义的行为”,GCC至少总是会产生
false
/0。@Dietrich,为什么这应该是未定义的行为?很抱歉,它通常不会调用未定义的行为(尽管在
short
int
具有相同范围的系统上会调用)。我错过了integer促销的一个细微差别。但是,在标准定义了行为的系统上,比较总是返回
false
。(比较
(unsigned)x==(int)y
总是未定义的,这是我最初的想法。)其要点是对于
GLushort x
x==(GLushort)-1
总是按照询问者想要的方式工作,
x==-1
总是错误的(除了在深奥系统上,它是未定义的)。好的,我收回这一点,这不是未定义的行为。我总是忘记在整数升级之后,“通常的算术转换”适用。整数提升(§6.3.1.1)仅从级别较低的类型提升为
int
无符号
,优先选择
int
,除非它不能表示原始类型的所有可能值。由于
unsigned
int
始终具有相同的秩(因为
unsigned
unsigned int
的缩写,natch),有符号值转换为unsigned(§6.3.1.8)。这意味着
UINT\u MAX==-1
但是
USHRT\u MAX!=-1
在深奥的平台上除外。测试证实了这一点。你们真是太棒了!谢谢