什么是NULL + INT的结果? [英] What is the result of NULL + int?

查看:310
本文介绍了什么是NULL + INT的结果?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经看到在OpenGL VBO实现中使用下面的宏之中:

I have seen the following macro being used in OpenGL VBO implementations:

#define BUFFER_OFFSET(i) ((char *)NULL + (i))
//...
glNormalPointer(GL_FLOAT, 32, BUFFER_OFFSET(x));

你能提供关于如何这个宏作品详细一点?它可以用函数来代替?
更确切地说,什么是递增NULL指针的结果?

Could you provide a little detail on how this macro works? Can it be replaced with a function? More exactly, what is the result of incrementing a NULL pointer?

推荐答案

让我们回一趟通过的OpenGL的肮脏的历史。曾几何时,有OpenGL的1.0。你用在glBegin glEnd 做绘图,仅此而已。如果你想快速绘制,你在显示列表卡住的东西。

Let's take a trip back through the sordid history of OpenGL. Once upon a time, there was OpenGL 1.0. You used glBegin and glEnd to do drawing, and that was all. If you wanted fast drawing, you stuck things in a display list.

然后,有人有好主意,能够只取物体渲染的阵列。因而诞生的OpenGL 1.1,它给我们带来了这样的功能如 glVertexPointer 。您可能注意到,这一功能在单词指针结束。这是因为它需要指向实际内存,这将是访问时的一个 glDraw * 的功能套件被调用。

Then, somebody had the bright idea to be able to just take arrays of objects to render with. And thus was born OpenGL 1.1, which brought us such functions as glVertexPointer. You might notice that this function ends in the word "Pointer". That's because it takes pointers to actual memory, which will be accessed when one of the glDraw* suite of functions is called.

快进几年。现在,人们希望把顶点数据在GPU内存,但他们不希望在显示列表信任。那些过于隐蔽,而且也没有办法知道你是否会得到与他们出色的表现。输入缓冲区对象。

Fast-forward a few more years. Now, people want to put vertex data in GPU memory, but they don't want to trust in display lists. Those are too hidden, and there's no way to know whether you'll get good performance with them. Enter buffer objects.

不过,由于ARB不得不让一切尽可能向后兼容(不管它多么的愚蠢作出的API的样子)的绝对的政策,他们决定,最好的方式来实现,这是刚刚再次使用相同的功能。只是现在,有从需要一个指针修改 glVertexPointer 的行为在全球开关取一个字节从一个缓冲区对象所抵消。该交换机被否的缓冲区对象绑定到 GL_ARRAY_BUFFER

However, because the ARB had an absolute policy of making everything as backwards compatible as possible (no matter how silly it made the API look), they decided that the best way to implement this was to just use the same functions again. Only now, there's a global switch that changes glVertexPointer's behavior from "takes a pointer" to "takes a byte offset from a buffer object." That switch being whether or not a buffer object is bound to GL_ARRAY_BUFFER.

当然,至于C / C ++而言,还是功能需要的指针的。和C / C规则++不允许你整数关口作为一个指针。没有一个演员。这就是为什么像 BUFFER_OBJECT 宏存在。这是一种方式来转换整数字节偏移量的指针。

Of course, as far as C/C++ is concerned, the function still takes a pointer. And the rules of C/C++ do not allow you to pass an integer as a pointer. Not without a cast. Which is why macros like BUFFER_OBJECT exist. It's one way to convert your integer byte offset into a pointer.

(的char *)NULL 部分简单地取NULL指针(这通常是无效* )和把它变成一个的char * 。在 + I 少了点在的char *指针运算。因为NULL通常是一个零值,加入 I 来将递增字节由偏移我,从而产生一个指针谁是值的字节偏移你过去了。

The (char *)NULL part simply takes the NULL pointer (which is usually a void*) and turns it into a char*. The + i just does pointer arithmetic on the char*. Because NULL is usually a zero value, adding i to it will increment the byte offset by i, thus generating a pointer who's value is the byte offset you passed in.

当然,C ++规范列出BUFFER_OBJECT的结果的未定义行为的。通过使用它,你真的依靠编译器做一些合理的。毕竟, NULL 不的有无的为零;所有的规范说的是,它是一个实现定义的空指针常量。它不具有在所有具有零值。在最真实的系统中,它会的。但事实并非如此的有无的到。

Of course, the C++ specification lists the results of BUFFER_OBJECT as undefined behavior. By using it, you're really relying on the compiler to do something reasonable. After all, NULL does not have to be zero; all the specification says is that it is an implementation-defined null pointer constant. It doesn't have to have the value of zero at all. On most real systems, it will. But it doesn't have to.

这就是为什么我只是用一个演员。

That's why I just use a cast.

glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, 0, (void*)48);

这是不确定的行为无论哪种方式。但它也比打字BUFFER_OFFSET短。海湾合作委员会和Visual Studio似乎找到它合理的。它不依赖于宏观NULL的值。

It's undefined behavior either way. But it's also shorter than typing "BUFFER_OFFSET". GCC and Visual Studio seem to find it reasonable. And it doesn't rely on the value of the NULL macro.

就个人而言,如果我是更多的C ++迂腐,我会使用一个 reinter pret_cast<无效*> 就可以了。但我不是。

Personally, if I were more C++ pedantic, I'd use a reinterpret_cast<void*> on it. But I'm not.

你能不能写一个 glVertexAttribBuffer 这需要一个偏移量,而不是一个指针?绝对。但它不是一个交易的那么大。只要做一个演员。

Can you write a glVertexAttribBuffer that takes an offset rather than a pointer? Absolutely. But it's not that big of a deal. Just do a cast.

这篇关于什么是NULL + INT的结果?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆