PDA

View Full Version : Origin of "GLvoid"



Paul Martz
09-03-2005, 11:36 AM
(This might seem like a pretty basic question, but I figure it requires some fairly in-depth knowledge of the spec, so I'm posting to the "Advanced" group...)

Does anyone know where the "GLvoid" data type comes from, as used in gl.h/glext.h?

In the OpenGL spec, Table 2.2 lists OpenGL data types, and notes that (in the C binding) they are prefixed with "GL", thus "double" becomes "GLdouble", etc. However, note that "void" doesn't appear in this table, so the usage of "GLvoid" in gl.h/gext.h appears to come out of nowhere.

The spec uses "void" in function prototypes as a return type, for commands that take no parameters, and as "void*" and "void**" for command parameter types.

gl.h/glext.h similarly use "void" for return types and commands that take no parameters (e.g., "void glEnd(void)"). However, they use "GLvoid*" and "GLvoid**" for command parameter types.

If "GLvoid" is correct as a parameter type, then why not as a return type? Shouldn't "void" be listed in Table 2.2 with a bit-width of "not applicable"? Or should gl.h/glext.h simply use "void" throughout -- for parameters as well as return types?

Any background info would be appreciated.

Korval
09-03-2005, 11:33 PM
Everywhere you see "GLVoid" pretend it said "void". That's what the compiler does.

Problem solved.

dorbie
09-04-2005, 12:25 AM
I don't know the reason for this but I'll speculate.

void as a return type means no return value, however a pointer to void has a size and portable size is the reason for the GL typedefs.

IMHO in this case it may be a waste since pointer dimensions are machine specific and cannot be typedef'd to provide portability unlike ints floats etc.

Maybe it was just done for symmetry, pointer to a typedef'd GLVoid doesn't buy you more portability.

Bob
09-04-2005, 01:01 AM
Originally posted by dorbie:
I don't know the reason for this but I'll speculate.

void as a return type means no return value, however a pointer to void has a size and portable size is the reason for the GL typedefs.

IMHO in this case it may be a waste since pointer dimensions are machine specific and cannot be typedef'd to provide portability unlike ints floats etc.

Maybe it was just done for symmetry, pointer to a typedef'd GLVoid doesn't buy you more portability.Personally, I doubt "portable size" is the reason for GL-types. Just look at Table 2.2 on page 9 in the 2.0 specification and the reason should be obvious; the specification does not define a specific size, but a minimum size. That means the actual size is implementation defined, but must be of at least x bits.

If you allow me to speculate, I think it's about guaranteeing a certain precision. Take glColor3us() as an example. unsigned short is guaranteed to be at least 16 bits, meaning when you use that function, you are guaranteed to specify the color within at least 1/65536:th. This, of course, doesn't mean anything if the internal precision isn't that much, but when it is, you know that glColor3us can guarantee that the color precision is high enough.

Anyway, this was off topic, just a side track regarding type sizes.

Now, regarding the GLvoid thing. Could it perhaps be that functions returning/accepting nothing in some languages doens't have a return/input type at all? I mean, in C and C++, a function returning/accepting nothing has a return/input type of void. But GLvoid, which conceptuallt means nothing aswell, may not work for some languages (as they require not type at all, not GLvoid). Therefore, void in the specifications means "nothing", and GLvoid when used as a pointer, just means "pointer to anything".

Paul Martz
09-04-2005, 10:33 AM
Thanks for the replies.

Yes, "void *" has a definite meaning in C -- a pointer to anything. Unfortunately, that makes me wonder, couldn't the (C-binding) gl.h/glext.h get along just fine using "void*" and "void**" for parameter types? "GLvoid*" and "GLvoid**" seem unnecessary in this light.

Furthermore, it almost seems like a bug in the spec that there is no type for "pointer to anything" that would be language independent. When the spec uses "void*" and "void**" in its function prototypes, it seems to rely too heavily on C semantics.

Overmind
09-04-2005, 12:57 PM
I think GLvoid is just consistent. Every datatype used in GL has a GL prefix. And in the spec the GL prefix is always omitted.

void glEnd(void) is correct C syntax for a function without parameters and without return value. In other languages there may be different syntax for these, for example in pascal you use "procedure" for a function without return value and "()" for no parameter.

In contrast to that, GLvoid * is not nothing, it's a pointer to the OpenGL datatype void (with a GL prefix like every OpenGL datatype).

Besides the symmetry with the rest of the types, that's the only way this can be done portably, because there are languages with no equivalent to a "void" type. Then you can just typedef GLvoid to some other type (e.g. char) and it will work without further changes.

Bob
09-04-2005, 01:56 PM
Originally posted by Paul Martz:
Thanks for the replies.

Yes, "void *" has a definite meaning in C -- a pointer to anything. Unfortunately, that makes me wonder, couldn't the (C-binding) gl.h/glext.h get along just fine using "void*" and "void**" for parameter types? "GLvoid*" and "GLvoid**" seem unnecessary in this light.

Furthermore, it almost seems like a bug in the spec that there is no type for "pointer to anything" that would be language independent. When the spec uses "void*" and "void**" in its function prototypes, it seems to rely too heavily on C semantics.Given my thoughts on it from my post, and Overminds post, the differnce between void and GLvoid, apart from concistency where all GL-types have the GL-prefix, is just how to treat them conceptually; void means nothing, and GLvoid means anything. Nothing really means nothing, but anything means there really IS something, just not any particular (predetermined) type.

Paul Martz
09-04-2005, 03:18 PM
I'd buy the "consistency" argument, if "void" appeared in Table 2.2, but it doesn't.

I'm not sure I buy the portability argument. Portability to other languages? These are the C-bindings. "void*/void**" should suffice, and won't vary from one C implementation to another.

I like the conceptual interpretation that "GLvoid means anything" -- but is there a clause in the spec to back that up? Or is it implicit, since p6 of the spec states that function prototypes are C prototypes, therefore "void*" is well-defined as a pointer to anything?

Bob
09-05-2005, 02:37 AM
Table 2.2 describes data types in OpenGL, but I'm not sure I would concider void/GLvoid to be data types, as they don't contain any data themselves.

Anyway, I think you're focusing too much on implementation details, which is not something the specification cares about. Using void * instead of GLvoid * for parameters would work just fine, just like using int instead of GLint works, and using GLfloat instead of float works. This assumes, of course, that GLvoid/GLint/GLfloat is typedefed as void/int/float.

What is important is that GL-types and types for functions match. If you define a variable of type GLvoid *, you can pass it to any function required by the specification to accept a GLvoid *. Whether GLvoid is typedefed as something other that void (technically, that IS legal) on some particular implementation is a different issue, but this variable you try to pass is know to be of the correct type as defined by the specification.

V-man
09-05-2005, 04:09 AM
I agree, GLvoid is useless. void is sufficient.
GLfloat is likely to be a 32 bit float for a long time. Ditto for some of the others.

GLint however can be nasty. I am not interested in these turning into 64 bit on a 64 bit system.

Paul Martz
09-05-2005, 07:49 AM
Yes, I'm definitely focusing on the implementation. And probably too much so.

Thanks for the good posts, all.