5

This is really a question about C++, not OpenGL. I'm following this tutorial on OpenGL (I've just started), and the author uses C++ (not C). My problem is that glVertexAttribPointer takes an offset parameter as const void*. Since this parameter simply tells OpenGL where a given vertex attribute appears for the first time in the array of vertices that was copied with glBufferData(), I would expect that it should be of std::ptrdiff_t type. This post on SO explains the reason why void* is used as an argument type, but I wonder why such a usage is legal in C++. For instance, the mentioned tutorial simply casts to void* the value of the offset in bytes, like in the call below:

glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void*)(3* sizeof(float)));

It seems to me that this approach cannot be legal because the cpprefence documentation of reinterpret_cast says

A value of any integral or enumeration type can be converted to a pointer type. A pointer converted to an integer of sufficient size and back to the same pointer type is guaranteed to have its original value, otherwise the resulting pointer cannot be dereferenced safely (the round-trip conversion in the opposite direction is not guaranteed the same pointer may have multiple integer representations)

So, if I understand this correctly, the std::ptrdiff_t value of the offset (which seems to be the one that is needed here) can be lost after the cast to void*. What do I miss?

Adrian
  • 987
  • 5
  • 13
  • 1
    Yes, it is legal C++. What's technically not legal is doing pointer arithmetic on a null pointer, which is what you're forced to do, when using buffer objects, see https://stackoverflow.com/questions/8283714/what-is-the-result-of-null-int – datenwolf Nov 19 '19 at 11:24
  • 1
    @datenwolf, well I'm actually asking about the fact that the round trip conversion int --> ptr --> int can change the value of int, which suggests that it cannot be legal. – Adrian Nov 19 '19 at 11:37
  • 3
    It’s indeed invalid. See also comments on https://stackoverflow.com/q/58679610/1968. – Konrad Rudolph Nov 19 '19 at 11:59
  • @Konrad Rudolph Thanks, that's exactly what I wanted to know! So the OpenGL API is unfortunate, and not my understanding of reinterpret_cast :) – Adrian Nov 19 '19 at 12:16
  • 1
    @Adrian Yeah, the API is … crap. Even if it were valid (it might be in C, no idea), it’s independently bad because passing a number as `void*` has no benefit. – Konrad Rudolph Nov 19 '19 at 12:17
  • @Konrad That was exactly bothering me, thanks again. – Adrian Nov 19 '19 at 12:19
  • Possible duplicate of [How to cast int to const GLvoid* ?](/questions/23177229/how-to-cast-int-to-const-glvoid) – n. m. could be an AI Nov 19 '19 at 12:42
  • @n. 'pronouns' m. I was asking why this is legal (in world with int --> ptr --> int conversion that can change the original int) and not how to make it compile – Adrian Nov 19 '19 at 13:38
  • The answers to the linked question talk about legality of this too. (It's not really legal) – n. m. could be an AI Nov 19 '19 at 13:43
  • 1
    @Adrian: "*So the OpenGL API is unfortunate*" Nobody's making you use [bad APIs in OpenGL](https://stackoverflow.com/q/37972229/734069). – Nicol Bolas Nov 19 '19 at 14:32

1 Answers1

4

"Not guaranteed " does not mean "guaranteed to fail"; it means "not guaranteed". Which means the implementation may or may not preserve the conversion.

The glVertexAttribPointer API requires an implementation of C or C++ that preserves integer->pointer->integer conversions. Much like it requires a C or C++ implementation that offers IEEE-754 floating-point types, as well as 8/16/32-bit integers.

Nicol Bolas
  • 449,505
  • 63
  • 781
  • 982
  • OK, thanks -- I just wanted to be sure, that it imposes additional requirements on implementation. BTW -- your comment above is also very helpful. – Adrian Nov 19 '19 at 21:07