<p>GL's types aren't true types but <code>typedef</code>s for platform types. So when you think about <code>GLuint</code> <em>vs.</em> <code>unsigned int</code>, you should consider that in the same way you consider <code>unsigned int</code> <em>vs.</em> <code>uint32_t</code>. If you are only writing for a single platform, you should read your system's <code>GL/gl.h</code> and pay attention to the section that looks like this:</p>

<pre><code>typedef unsigned int    GLenum;
typedef unsigned char   GLboolean;
typedef unsigned int    GLbitfield;
typedef void        GLvoid;
typedef signed char GLbyte;     /* 1-byte signed */
typedef short       GLshort;    /* 2-byte signed */
typedef int     GLint;      /* 4-byte signed */
typedef unsigned char   GLubyte;    /* 1-byte unsigned */
typedef unsigned short  GLushort;   /* 2-byte unsigned */
typedef unsigned int    GLuint;     /* 4-byte unsigned */
typedef int     GLsizei;    /* 4-byte signed */
typedef float       GLfloat;    /* single precision float */
typedef float       GLclampf;   /* single precision float in [0,1] */
typedef double      GLdouble;   /* double precision float */
typedef double      GLclampd;   /* double precision float in [0,1] */
</code></pre>

<p>If your coding standard says you should always use the old C types instead of the guaranteed-width types like <code>uint32_t</code>, and you should avoid unnecessary casts, maybe it makes sense to just use the appropriate native type instead of the GL names. As Nicol Bolas says, it avoids having to include <code>GL/gl.h</code>. If your coding standard prefers using the guaranteed-width types, maybe it makes sense to keep using those in your non-GL code, and to think more carefully about when you pass those to functions taking GL type names.</p>

<p>If you avoid explicit casts wherever possible and you compile with warnings enabled, it'll be much easier to switch to a new platform where the <code>typedef</code>s are different, because the compiler will warn you about numeric conversions that might lose information. If you explicitly cast from (say) <code>GLint</code> to <code>int</code>, but then move to a platform where <code>int</code> is 16-bit and <code>GLint</code> is a <code>typedef</code> for <code>uint32_t</code>, then the explicit cast will stop the compiler warning you about the narrowing conversion.</p>

CC BY-SA 3.0
2017-11-13T10:38:51.130Z
2017-11-13T10:38:51.130Z
Dan Hulme
<p>Yes, there's a time not to use GL types when interacting with OpenGL: <code>GLvoid</code>. There is absolutely no reason to use this type.</p>

<p>With everything else (assuming you're using a "standard" OpenGL loader), you should use OpenGL's types when <em>talking to OpenGL</em>. That is, the values you pass to OpenGL functions should be in OpenGL's types. This may mean that a function that talks to OpenGL may need an OpenGL data type in its function parameter list. This should be avoided where possible, to prevent you from creating dependencies between OpenGL code and non-OpenGL code.</p>

<p>However, if you don't mind having large portions of your application have dependencies on OpenGL, you may use OpenGL's data types throughout your code.</p>

<p><a href="https://www.khronos.org/opengl/wiki/OpenGL_Type" rel="nofollow noreferrer">OpenGL's data types</a> are specified to have a particular bitdepth. As such, they are (conceptually, if not strictly C++-legally) pointer-interconvertible to certain types defined in <code>&lt;stdint.h&gt;/&lt;cstdint&gt;</code>. Indeed, many OpenGL headers will check for the existence of this header and use it wherever it is available to define OpenGL's data types. As such, if you want a fixed bitdepth integer, you have a choice besides using OpenGL's data types.</p>

<blockquote>
  <p>I am wondering if there is any case where using the GL types could cause issues when it it is not explictly clear that the values are coming from OpenGL.</p>
</blockquote>

<p>OpenGL is C, not <em>magic</em>. A function in C cannot have any control over the return value of the function that calls it. Even a C++ function cannot; at best, it can throw an exception, but this still doesn't have anything to do with its caller's return value.</p>

CC BY-SA 3.0
2017-11-12T02:32:27.357Z
So to sum up *never* (even when talking to OpenGL) use `GLvoid` and only use GLtypes when talking to OpenGL.  If you need fixed bitdepth integers in your code that does not talk to OpenGL use `cstdint`?
Startec
CC BY-SA 3.0
2017-11-12T02:37:37.610Z
And why never use `GLvoid`?
Startec
CC BY-SA 3.0
2017-11-12T02:47:59.233Z
`GLuint` has a meaning that is distinct from the fundamental type `unsigned int`. `GLvoid` is no different from `void`.
Nicol Bolas
CC BY-SA 3.0
2017-11-13T20:16:25.147Z
On my system I see `typedef unsigned int    GLuint;` and `typedef void        GLvoid;` so how is `GLvoid` no different but `GLuint` is?
Startec
CC BY-SA 3.0
2017-11-13T20:18:25.890Z
@Startec: Headers will redefine `GLuint` based on the platform(s) they work on. `GLvoid` will *always* be defined as `void`.
Nicol Bolas
CC BY-SA 3.0
2017-11-15T10:58:36.497Z
@Startec You can as well look at it with the logic you use in your question. `GLuint` makes sense, because you communicate that value to the GL, you either put it into a GL function or it's returned from a GL function. But that `GLvoid` function is **your** function, a C++ function that doesn't return anything anyway, let alone a GL value, you don't go `return glWhatever(...);`, since you don't return anything. `void` is just not a meaningful *data* type, whose representation would have any relevance, because it has none.
Christian Rau
CC BY-SA 3.0
2017-11-12T02:27:15.337Z
2017-11-15T04:40:24.777Z
2017-11-15T04:40:24.777Z
Nicol Bolas
<p>If I am writing my own function to check shader compile errors, or do anything that interacts with the OpenGL API but ultimately returns as a result of my application code, should I use the C++ <code>void</code> or <code>GLvoid</code>?</p>

<p>I.E.</p>

<pre><code>GLvoid Shader::check_compile_errors(GLuint ComputeShader, std::string type)
{
    const GLint log_length{ 1024 };
    GLchar info_log[log_length];
    GLint success;

    if (type == "PROGRAM")
    {
        glGetProgramiv(ComputeShader, GL_LINK_STATUS, &amp;success);
        if (!success)
        {
            glGetProgramInfoLog(ComputeShader, log_length, nullptr, info_log);
            std::cout &lt;&lt; "ERROR::PROGRAM_LINKING_ERROR of type: " &lt;&lt; type &lt;&lt; "\n" &lt;&lt; info_log &lt;&lt; "\n ---- " &lt;&lt; std::endl;
        }
    }
 // Here the return is implicitly void, but from C++ not OpenGL!
}
</code></pre>

<p>I realize here that <code>GLvoid</code> is typedef'd to void but I am wondering if there is any case where using the GL types could cause issues when it it is not explictly clear that the values are coming from OpenGL.</p>

<p>Another example would be writing an image to a file (from <code>glReadPixels</code>). If I am setting fields in the header which normally takes things in the form <code>unsigned char</code> should I change that to a <code>GLuchar</code>?</p>

<opengl><types>
Is there ever a time when I should *not* use the GL* types?
Startec
# Is there ever a time when I should *not* use the GL* types?

(Asked by: username_0 on 2017-11-12)

If I am writing my own function to check shader compile errors, or do anything that interacts with the OpenGL API but ultimately returns as a result of my application code, should I use the C++ `void` or `GLvoid`?

I.E.

```
GLvoid Shader::check_compile_errors(GLuint ComputeShader, std::string type)
{
    const GLint log_length{ 1024 };
    GLchar info_log[log_length];
    GLint success;

    if (type == "PROGRAM")
    {
        glGetProgramiv(ComputeShader, GL_LINK_STATUS, &success);
        if (!success)
        {
            glGetProgramInfoLog(ComputeShader, log_length, nullptr, info_log);
            std::cout << "ERROR::PROGRAM_LINKING_ERROR of type: " << type << "\n" << info_log << "\n ---- " << std::endl;
        }
    }
 // Here the return is implicitly void, but from C++ not OpenGL!
}

```

I realize here that `GLvoid` is typedef'd to void but I am wondering if there is any case where using the GL types could cause issues when it it is not explictly clear that the values are coming from OpenGL.

Another example would be writing an image to a file (from `glReadPixels`). If I am setting fields in the header which normally takes things in the form `unsigned char` should I change that to a `GLuchar`?

**Tags:** opengl, types


---

## 2 answers

### Answer by username_2 on 2017-11-12. Score: 4 | Accepted answer

Yes, there's a time not to use GL types when interacting with OpenGL: `GLvoid`. There is absolutely no reason to use this type.

With everything else (assuming you're using a "standard" OpenGL loader), you should use OpenGL's types when *talking to OpenGL*. That is, the values you pass to OpenGL functions should be in OpenGL's types. This may mean that a function that talks to OpenGL may need an OpenGL data type in its function parameter list. This should be avoided where possible, to prevent you from creating dependencies between OpenGL code and non-OpenGL code.

However, if you don't mind having large portions of your application have dependencies on OpenGL, you may use OpenGL's data types throughout your code.

[OpenGL's data types](https://www.khronos.org/opengl/wiki/OpenGL_Type) are specified to have a particular bitdepth. As such, they are (conceptually, if not strictly C++-legally) pointer-interconvertible to certain types defined in `<stdint.h>/<cstdint>`. Indeed, many OpenGL headers will check for the existence of this header and use it wherever it is available to define OpenGL's data types. As such, if you want a fixed bitdepth integer, you have a choice besides using OpenGL's data types.

> I am wondering if there is any case where using the GL types could cause issues when it it is not explictly clear that the values are coming from OpenGL.

OpenGL is C, not *magic*. A function in C cannot have any control over the return value of the function that calls it. Even a C++ function cannot; at best, it can throw an exception, but this still doesn't have anything to do with its caller's return value.

> **Comments:**
> **username_0**: So to sum up *never* (even when talking to OpenGL) use `GLvoid` and only use GLtypes when talking to OpenGL.  If you need fixed bitdepth integers in your code that does not talk to OpenGL use `cstdint`?  
> **username_0**: And why never use `GLvoid`?  
> **username_2**: `GLuint` has a meaning that is distinct from the fundamental type `unsigned int`. `GLvoid` is no different from `void`.  
> **username_0**: On my system I see `typedef unsigned int    GLuint;` and `typedef void        GLvoid;` so how is `GLvoid` no different but `GLuint` is?  
> **username_2**: @username_0: Headers will redefine `GLuint` based on the platform(s) they work on. `GLvoid` will *always* be defined as `void`.  
> **username_3**: @username_0 You can as well look at it with the logic you use in your question. `GLuint` makes sense, because you communicate that value to the GL, you either put it into a GL function or it's returned from a GL function. But that `GLvoid` function is **your** function, a C++ function that doesn't return anything anyway, let alone a GL value, you don't go `return glWhatever(...);`, since you don't return anything. `void` is just not a meaningful *data* type, whose representation would have any relevance, because it has none.  

---

### Answer by username_1 on 2017-11-13. Score: 2

GL's types aren't true types but `typedef`s for platform types. So when you think about `GLuint` *vs.* `unsigned int`, you should consider that in the same way you consider `unsigned int` *vs.* `uint32_t`. If you are only writing for a single platform, you should read your system's `GL/gl.h` and pay attention to the section that looks like this:

```
typedef unsigned int    GLenum;
typedef unsigned char   GLboolean;
typedef unsigned int    GLbitfield;
typedef void        GLvoid;
typedef signed char GLbyte;     /* 1-byte signed */
typedef short       GLshort;    /* 2-byte signed */
typedef int     GLint;      /* 4-byte signed */
typedef unsigned char   GLubyte;    /* 1-byte unsigned */
typedef unsigned short  GLushort;   /* 2-byte unsigned */
typedef unsigned int    GLuint;     /* 4-byte unsigned */
typedef int     GLsizei;    /* 4-byte signed */
typedef float       GLfloat;    /* single precision float */
typedef float       GLclampf;   /* single precision float in [0,1] */
typedef double      GLdouble;   /* double precision float */
typedef double      GLclampd;   /* double precision float in [0,1] */

```

If your coding standard says you should always use the old C types instead of the guaranteed-width types like `uint32_t`, and you should avoid unnecessary casts, maybe it makes sense to just use the appropriate native type instead of the GL names. As username_2 username_2 says, it avoids having to include `GL/gl.h`. If your coding standard prefers using the guaranteed-width types, maybe it makes sense to keep using those in your non-GL code, and to think more carefully about when you pass those to functions taking GL type names.

If you avoid explicit casts wherever possible and you compile with warnings enabled, it'll be much easier to switch to a new platform where the `typedef`s are different, because the compiler will warn you about numeric conversions that might lose information. If you explicitly cast from (say) `GLint` to `int`, but then move to a platform where `int` is 16-bit and `GLint` is a `typedef` for `uint32_t`, then the explicit cast will stop the compiler warning you about the narrowing conversion.


---

