5

This works but also results in "Don't use reinterpret_cast (type.1)" warning:

glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 8,
  reinterpret_cast<void*>(sizeof(GLfloat) * 3));

This doesn't compile:

glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 8,
  static_cast<void*>(sizeof(GLfloat) * 3));

This doesn't compile:

glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 8,
  dynamic_cast<void*>(sizeof(GLfloat) * 3));

This obviously works but seems to be a big no-no in C++ ("Don't use C-style casts (type.4)")

glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 8,
  (void*)(sizeof(GLfloat) * 3));

Should i just ignore the warning about the reinterpret_cast?

Mat
  • 202,337
  • 40
  • 393
  • 406
Big Temp
  • 434
  • 4
  • 12
  • Are you sure you want to convert **int** and not __int*__? – CoderCharmander Nov 03 '19 at 11:15
  • 1
    @CoderCharmander Yes, the last argument of `glVertexAttribPointer` is of a type `const GLvoid*` but represents an array offset in bytes. – Big Temp Nov 03 '19 at 11:20
  • 5
    The *API* violates the C++ Core guidelines (and it’s, frankly, a bad API). As such there’s really no way of avoiding the (entirely justified) warning: the result of this cast is *implementation defined* and a conforming C++ compiler is not required to support a meaningful interpretation of it. You can “silence” the warning by moving the cast into its own function. – Konrad Rudolph Nov 03 '19 at 11:22
  • 1
    Possible duplicate https://stackoverflow.com/questions/23177229 – n. m. could be an AI Nov 03 '19 at 11:22
  • 2
    `size_t` is guaranteed to be large enough to hold the size of any continuously allocatable memory. Although pretty likely, there's no rule that it's size must be equal to the size of a pointer. So you actually would need an intermediate cast to `uintptr_t`: `reinterpret_cast(static_cast(...))`. That won't avoid the warning, of course, but at least is semantically correct. – Aconcagua Nov 03 '19 at 11:24
  • @Rabbid76 The link in your first comment gives 404 – M.M Nov 03 '19 at 11:28
  • Some compilers offer a [pragma](https://stackoverflow.com/questions/3378560/how-to-disable-gcc-warnings-for-a-few-lines-of-code) (or other means) to suppress the warning. Don't consider that as recommendation to generally turning that warning off, you might do so just for this very specific situation and turn it on again directly afterwards. – Aconcagua Nov 03 '19 at 11:35
  • @n.m. in the suggested duplicate the best answer does violate the coreguidelines , so I think that is not really a duplicate of this question – M.M Nov 03 '19 at 11:38
  • @M.M The real answer is "nope, no way". The duplicate is supposed to illustrate that. – n. m. could be an AI Nov 03 '19 at 12:11

1 Answers1

6

When you're doing low-level programming, you will occasionally have to do things that the C++ core guidelines say you shouldn't do. So just do them and either live with the "warning" or turn off that specific guideline (possibly on a per-file basis).

That having been said, the need for this particular bit of low-level fudgery is solely because of OpenGL's stupidity in its vertex specification API. That value ought to be an integer byte offset of some sort, not an offset cast to a pointer which the other side will cast back to an offset.

So it would be better to just avoid the bad API altogether. Use separate attribute format specification rather than the old-style glVertexAttribPointer. It's superior in pretty much every way. It will turn your code from:

glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 8,
  reinterpret_cast<void*>(sizeof(GLfloat) * 3));

to

glVertexAttribFormat(1, 3, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 3); //Offset specified as integer.
glVertexAttribBinding(1, 0); //You seem to be using multiple attributes with a stride, so they should use the same buffer binding.

//Some later point when you're ready to provide a buffer.

glBindVertexBuffer(0, buffer_obj, 0, sizeof(GLfloat) * 8); //Stride goes into the buffer binding.

See, no casting at all.

Unfortunately, there are no alternatives for the glDrawElements family of functions, so you're still going to get this warning.

Nicol Bolas
  • 449,505
  • 63
  • 781
  • 982
  • Does this supercede your answer to [SO: What is the result of NULL + int?](https://stackoverflow.com/a/8283855/7478597)? I just amazed that I saw both links in comments to [SO: Is cast to void* in a glVertexAttribPointer call a legal C++?](https://stackoverflow.com/q/58932938/7478597). – Scheff's Cat Nov 19 '19 at 12:12
  • 1
    @Scheff: "*Does this supercede your answer to SO: What is the result of NULL + int??*" No. The NULL + int idiom is still bad. – Nicol Bolas Nov 19 '19 at 14:30