简体   繁体   English

为什么使用0xffffffff而不是-1?

[英]Why use 0xffffffff instead of -1?

I'm coming from a Java background and make my first steps in C++ graphics programming. 我来自Java背景,是C ++图形编程的第一步。 I worked on the ogl-dev tutorials ( http://ogldev.atspace.co.uk/ ) and noticed that a macro with value 0xffffffff is defined. 我研究了ogl-dev教程( http://ogldev.atspace.co.uk/ ),并注意到已定义了一个值为0xffffffff的宏。 I understand that it encodes -1, but what I do not understand is why I should prefer this encoding over just writing -1 . 我知道它编码为-1,但是我不明白的是为什么我宁愿只写-1而不喜欢这种编码。 Is it for (backwards) compatibility? 是为了(向后)兼容性吗? Does it have to do with some idiosyncracy of C? 它与C的某些特殊性有关吗? Is it an idiom? 这是成语吗?

An example: 一个例子:

#define ERROR_VALUE 0xffffffff

and subsequently 然后

GLuint location = glGetUniformLocation(m_shaderProg, uniformName);
    if (location == ERROR_VALUE)
        throw new exception("error happened");

why wouldn't I write 我为什么不写

if (location == -1)

or define my macro as 或将我的宏定义为

#define ERROR_VALUE -1

Thank you :) 谢谢 :)

If you check the OpenGL specification (particularly section 7.6., page 134), you will find that glUniformLocation is actually specified to return a GLint , which is a 32-Bit signed integer type. 如果检查OpenGL规范 (尤其是第134页的7.6节),则会发现glUniformLocation实际上已指定为返回GLint ,后者是32位带符号整数类型。 Calling glUniformLocation is equivalent to a call to glGetProgramResourceLocation , which has a return type of GLint as well and is specified to return the value -1 upon error. 调用glUniformLocation等效于对glGetProgramResourceLocation的调用,后者也具有GLint的返回类型,并且被指定为在发生错误时返回值-1 The comparison of location to the 0xFFFFFFFF put there via replacement of the ERROR_VALUE macro just happens to work in the tutorial code because location is a GLuint rather than a GLint . 通过替换ERROR_VALUE宏将location0xFFFFFFFF进行比较,恰好在本教程代码中起作用,因为locationGLuint而不是GLint If glUniformLocation actually returns -1 there, the -1 will first be implicitly converted to GLuint . 如果glUniformLocation实际上在那里返回-1 ,则首先将-1隐式转换为GLuint This implicit conversion will follow modulo arithmetic and the -1 will wrap around to become 0xFFFFFFFF since GLuint is a 32-Bit unsigned integer type. 由于GLuint是32位无符号整数类型,因此此隐式转换将遵循模运算,并且-1将环绕以变为0xFFFFFFFF If location was of signed type instead, this would not work correctly. 如果location是签名类型,那么它将无法正常工作。 As has been pointed out by Nicol Bolas, if you want to compare to some constant to check for success of this function, compare the result to GL_INVALID_INDEX which is there for exactly this purpose. 正如Nicol Bolas所指出的那样,如果您想与某个常数进行比较以检查此函数是否成功,请将结果与GL_INVALID_INDEX进行比较,以达到此目的。 Contrary to the macro defined in the tutorial code, GL_INVALID_INDEX is specified to be an unsigned integer of value 0xFFFFFFFF , which will cause any comparison to work out correctly because of the usual arithmetic conversions 与教程代码中定义的宏相反, GL_INVALID_INDEX被指定为值为0xFFFFFFFF的无符号整数,由于通常的算术转换 ,这将导致任何比较都能正确进行……

As others have also noted in the comments above, I would not recommend that you consider the code presented in these tutorials to be representative of good C++. 正如其他人在上面的评论中也指出的那样,我不建议您考虑将这些教程中提供的代码视为良好的C ++的代表。 Using macros to define constants in particular is anything but great (see, eg, here for more on that). 使用宏来定义常量尤其无济于事(例如,请参阅此处的更多内容)。 We also don't normally use new to allocate an exception object to throw like here: 我们通常也不会使用new来分配异常对象,例如:

throw new exception("error happened");

In general, you'll want to avoid new in C++ unless you really need it (see, eg, here for more on that). 通常,除非确实需要C ++,否则您将避免使用C ++中的new (例如,请参阅此处的更多内容)。 And if dynamic memory allocation is indeed what you need, then you'd use RAII ( smart pointers ) to take care of correctly handling the resource allocation… 如果确实需要动态内存分配,则可以使用RAII智能指针 )来正确处理资源分配……

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM