Re: Anybody here endure C/Cpp? (.h to .inc conversion)
From: Beth (BethStone21_at_hotmail.NOSPICEDHAM.com)
Date: 01/02/05
- Next message: Beth: "Re: wanna do something nerdy and cool?"
- Previous message: marcus: "Re: Anybody here endure C/Cpp? (.h to .inc conversion)"
- In reply to: marcus: "Anybody here endure C/Cpp? (.h to .inc conversion)"
- Next in thread: Phil Carmody: "Re: Anybody here endure C/Cpp? (.h to .inc conversion)"
- Reply: Phil Carmody: "Re: Anybody here endure C/Cpp? (.h to .inc conversion)"
- Reply: marcus: "Re: Anybody here endure C/Cpp? (.h to .inc conversion)"
- Reply: NoDot: "Re: Anybody here endure C/Cpp? (.h to .inc conversion)"
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
Date: Sun, 02 Jan 2005 06:26:55 GMT
marcus wrote:
> I'm attempting to convert .h files to .INC as something useable in ASM
> syntax. And I'm a bit of a newbiean.
>
> Can you tell me what this really does?:
>
> typedef void (APIENTRY * PFNGLPOINTPARAMETERFEXTPROC)
> (GLenum pname, GLfloat param);
One can guess...the problem is that the definitions of "APIENTRY" and
"GLenum" and such are _elsewhere_ in the file...
Do yourself a big favour...go on the 'Net and download "GREP" appropriate
to your system (if you're using a UNIX OS then you'll find it is already
installed...just type "man grep" to check that this is the case and also
get the lowdown on how to use it :)...
"GREP" is a utility perfectly designed for this kind of problem...it
searches through files looking for particular bits of text...and, simply,
use GREP to work your way down...
For example, this is the definition of "PFNGLPOINTPARAMETERFEXTPROC" but
what is "APIENTRY"? Ask GREP to look for "APIENTRY" and then find its
definition...substitute that definition in the current definition (that is,
"undo" the "typedef" or "#define" and write it out literally)...repeat
until you get a definition that's solely in terms of the "primitive" stuff
built into C, like "int", "float" or whatever...
>From the name and how these things normally work, you'll find that
"APIENTRY" is the _convention_ for the function...that is, it'll resolve to
some "_cdecl" or "declspec()" nonsense which defines it to use some C or
Pascal or Stdcall convention...
But, in the most general sense, this definition is defining
"PFNGLPOINTPARAMETERFEXTPROC" to be a type that's a pointer to a function
that has a "GLenum" and "GLfloat" parameter and returns nothing, following
the "APIENTRY" calling convention...what an "APIENTRY" resolves to or what
a "GLfloat" is exactly is defined elsewhere...
Typically, this is what we'd expect from some "callback" kind of
function...this "typedef" declaring the "type" that the function should
conform to (and, thus, if you write your "callback" function and then try
to "type" it to the absurdly-named "PFNGLPOINTPARAMETERFEXTPROC" data type,
it'll give you a type error when you screwed it up :)...
The irony is that in purely _physical_ terms, it's just an address...a
DWORD, using a 32-bit compiler, with an address in it...adding the
"abstraction" back in bit-by-bit: it's a DWORD with an address...this
address is a pointer to a function...this function has two parameters (a
"GLenum" followed by a "GLfloat") and follows the "APIENTRY" conventions
(whatever those are defined to be elsewhere in the file), returning
nothing...and the "typedef" turns this whole "pointer to an
APIENTRY-convention function with two parameters and no return" prototype
into a data type called "PFNGLPOINTPARAMETERFEXTPROC"...although, that's
such an absurdly long and complex name, it is questionable whether it's
easier to NOT bother with such a "typedef" in the first place...it's almost
as much to type with the "typedef" as it would be without...
> They mentioned a macro. I'm thinking the macro would be APIENTRY?
A macro? Oh dear...are you sure about that? Well, any of the user-defined
stuff ("APIENTRY", "GLenum", etc.) _could_ be a macro...you just can't tell
from this line alone...ordinarily, the "APIENTRY" kind of thing in that
position ends up equating to the "conventions" and "options" for a
function...you know, the "declspec()" / "_stdcall" optional (and often
"compiler-specific") nonsense like that...
> but the only thing that looks like it might be a function is:
> GLAPI extern
>
> Does * mean that PFNGLPOINTPARAMETERFEXTPROC is a pointer?
Yes...
> Why 2 sets of parenthesis?
Basically, to avoid "ambiguity"...consider:
--------------------------------------
typedef void * FUNCTION(int);
--------------------------------------
Do I mean a function that returns "void *" or do I mean a pointer to a
function that returns "void"? That is, do I mean "(void *)" or do I mean
"void (*)"?
It's ambiguous and "prone to error"...so, it's a convention in C to wrap
any such thing in parenthesis to make absolutely sure the reader and the
compiler are reading it the correct way:
--------------------------------------
typedef void (*FUNCTION)(int);
--------------------------------------
...clearly makes it a "pointer to a function that returns void" and not "a
function that returns void *"...
It's the same trick as wrapping a mathematical formula in parenthesis to
force it to be calculated in a particular order, regardless of any
"precedence rules"...indeed, it's good practice to do this all the time,
even if the compiler would have interpreted it correctly without the
brackets...just because it helps human readers to work out what's going
on...plus, it's conveniently "lazy" too...I confess I have no idea what the
"precedence rules" for most programming languages are (well, I know the
rough stuff: "*" and "/" will be higher than "+" and "-" usually :)...and
you don't need to know if you always wrap your stuff in parenthesis, like:
--------------------------------------
X = ((A / B) + (D * E)) / 2
--------------------------------------
...or whatever...easier for humans to read what the order should
be...ensures the compiler really does do it as you ask...excuses you from
ever finding out what the "precedence rules" are because you never depend
on them and put the order in _explicitly_ every time...
The parenthesis in the "typedef" is kind of similar in that it's done to
not only make sure that the compiler interprets it as "void (*)" and not
"void *" (which is different)...but it also helps out your human readers to
also work that out for themselves...of course, when you get absurd
unreadable names like "PFNGLPOINTPARAMETERFEXTPROC", these points are
nullified by the long, stupid name being quite unreadable...but that's
bloody "Hungarian notation" for you...
Ah, mind you, if you learn "Hungarian notation", then the name is
_supposed_ to give you a "hint"...for example, the "PFN" at the start is
saying "Pointer to FuNction"...the "GL" refers to "OpenGL" (so you know
what this "type" applies to, should you be using many libraries with absurd
"Hungarian" names)..."PROC" at the end suggests this is a "PROCedure" we're
pointing to, as well...the "EXT" means "EXTension", probably (just guessing
that)...and the "F", if I remember how OpenGL works, means this the
Floating point version because there are many different "versions" of the
same thing taking floating-point or vector or integer inputs or whatever...
"The clue is in the question" with Hungarian notation, apparently...but,
admittedly, the name is so absurd and long-winded, is it better with the
"hints" or without? ;)
> The pname and param are to end up as function params in a call:
>
> call glPointParameterfEXT, GLenum, GLfloat
>
> but who's pointer comes from whom? and what gets where how and from
> whence? :)
Right, this is working on the premise that OpenGL does it like most others
things do it (as I say, the entire definition is NOT on this one line but
depends on definitions elsewhere...would need to see those lines too, to be
absolutely sure :), then the basic idea here is that this is only a
_TYPE_...
In Plain English, the line is trying to say "whenever you see
PFNGLPOINTPARAMETERFEXTPROC from now on in the source code, that's
'shorthand' for a pointer to a function that takes two parameters (a
"GLenum" then a "GLfloat"), uses the APIENTRY conventions and returns
nothing"...
Note that it's a type for the pointer to the function, it is NOT that
function itself...typically, you see this kind of construction for
"callbacks"...that is, _YOU_ supply the "PFNGLPOINTPARAMETERFEXTPROC"
function to OpenGL (that calls this function at the appropriate time) and
NOT the other way around (that this is an OpenGL function you can call)...
The idea of "callbacks" being that you can supply OpenGL the pointer to a
function _YOU'VE_ created and then OpenGL calls this function as part of
its operations..."don't call us, we'll call you"...one classic example -
not from OpenGL but from the Windows GUI - is to supply a pointer to a
"window procedure"...this "window procedure" is something _YOU_ create and
it accepts parameters that tell it that certain "events" have
happened...and the idea is simply that when an "event" happens - say, the
user moves a window, requiring the newly exposed bit to be "painted" with
graphics - then Windows can _CALL_ your "window procedure" to do that...a
"don't call us, we'll call you" scheme...
[ Or, as another example (more suited to what you might actually find in
OpenGL somewhere :), you create a function that deals with, say, choosing
what colour to make a pixel in a line...then you call some "DrawLine"
function in OpenGL and supply a _pointer_ to your "ChooseColour"
function...as OpenGL draws each pixel of the line, it calls your
"ChooseColour" function with the appropriate parameters in order for your
function to tell it what colour to make the pixel...this, therefore, makes
the "DrawLine" more flexible and customisable because you can supply code
for OpenGL to actually run while it's drawing the line (OpenGL decides
_where_ to draw the pixel BUT _your_ function is consulted as to what
colour to make it :)...this is "DDA line-drawing"...this isn't - from what
I can see - what this particular "callback" function is doing but it'll
probably be a similar idea to that in some regard :) ]
> I dont see how C++ claims easier understanding.
Actually, this has nothing to do with C++ or OOP...this is perfectly valid
C code and is probably more likely to be found in C code than C++, in fact,
as C++ could use "virtual base classes" and things like that to do much the
same job instead...things like this existed before C++ did :)...
> Everything's abstracted from abstractions. Where's the beef?!
Now you begin to appreciate why we all end up on alt.lang.asm, dealing with
the actual machine and trying our best to ignore all the "abstractions on
the abstractions" of HLLs...
It's what I always say...the more "abstract" does NOT mean "the better" at
all...check out what "abstract" actually means...one definition is that
it's the act of "ignoring irrelevent details to aid focus"...that is, using
the HLL, you don't need to concern yourself with the "irrelevent detail" of
choosing which register to put something into or the "irrelevent details"
of how to make a C-convention function call...by taking these things away,
the idea is that you can concentrate - focus your attention - on the
program logic, not on "machine specifics"...that's the idea...
There is an inherent flaw in this plan, though...what defines an
"irrelevent detail"? Consider how, for example, C did not have any "calling
convention" stuff in it originally (everything was "C convention"
regardless)...but then compilers started adding on "compiler specific
extensions" like "_cdecl", "_pascal", "_stdcall", "_fastcall" to specify
other "calling conventions" for functions...
But - wait - didn't we declare "calling conventions" to be an "irrelevent
detail" by not including them in the original C standard? Yes, we did...the
problem is that _SOMETIMES_ it's an "irrelevent detail" and _SOMETIMES_
it's anything but...Windows, for example, uses "STDCALL" convention
throughout...this is incompatible with C convention...you need to link to
Delphi code? Well, then that "_pascal" calling convention isn't quite so
"irrelevent" a detail anymore, eh?
Practice has demonstrated the _flaw_ in the "theory"...the compiler added
these "compiler specific extensions" because whatever "theory" declares to
be an "irrelevent detail" isn't always so...the other great example of this
is that HLLs also declare the low-level machine instructions to be
similarly "irrelevent"...a nice theory...but then you look at nearly every
C compiler there is and they have an "_asm" compiler-specific extension
added...indeed, this was so common that C++ - unlike C - actually
_RESERVES_ the keyword "_asm" for "inline assembly" (doesn't define what
that assembly language will be, of course, because that's "machine
specific"...but it does define that "_asm" should be reserved for that
purpose by the C++ compiler :)...
"None so blind as those that can see"; I would point to these various
things as "reverse Darwinism"...or a variant of the "anthropic
principle"...which, in Plain English, means that these things appear
because they are _NEEDED_, regardless of what the "theory" suggests...
For example, if "calling conventions" were actually an "irrelevent detail"
then compiler writers would not add "compiler specific extensions" to
accomodate them...they do so because, often, they very much _AREN'T_
"irrelevent" at all...if low-level assembly language coding had no more
purpose (is "dead") in the modern era then none of these compilers would
have "inline assembly" either...this is added because, _YES_, it does
sometimes serve a purpose...
And, finally, we have to look at the claims some make about "modern
machines are so fast, we need not worry about optimisations or assembly
coding"...if that were true, then "inline assembly" wouldn't exist...but,
on the contrary, we instead find that nearly _every_ HLL compiler
(excluding only things like Java, for obvious "portability" reasons...but,
then again, Java still has its own "portable Java assembly" :) has it
included...if this were true, then no-one would ever complain about the
"bloat", "slowness" and "crapness" of Microsoft software...
It self-evidently isn't true because of what we see as our reality around
us...as I say, this is similar to the "anthropic principle" in
science...basically, it's a really easy scientific idea...simply, it states
that the universe _MUST_ be appropriate for human life to have
developed...what's the proof of that? Well, obviously, _WE_ are the proof
that this must be the case...if the universe was not appropriate for the
development of human life, then we wouldn't be around to ask the questions
in the first place...
This is my "assembly-thropic principle"...HLLs self-evidently _can't_ be
good enough because, if they were, there would never be any need to
"compromise" their "theory" with "compiler-specific extensions" like
"calling conventions" or "inline assembly"...or, basically, the means to
more or less "subvert" nearly any part of the HLL "abstraction"...
More over, C itself stands as even more proof because it's a highly popular
language (computer time is measured in "B.C." and "A.C."...before and after
the C language ;)...and what design element of the C language can we see
that accounts for how it picked up so much popularity? Simple, C does
"portable" but it resists "abstract" as far as it can...other HLLs are
"problem domain", C refuses to be that...for instance, if you need to do
something even so simple as concatenate two strings, you must call a
function from the "standard library" to do it (and if you don't use the
standard library, then, simply, you do it all on a character-by-character
low-level basis...and _you're_ responsible for making sure the
"allocations" are correct to fit the new string too :)...
C is _grudingly_ a HLL, so to speak...it doesn't want to "abstract" any
further than one overriding design consideration: "portability"...it'll
"abstract" enough to be "portable" but once it's done that, C _stops_ and
goes no further...it is a language that doesn't _want_ to be "abstract"
anymore than it can help (remembering that it does want to be "portable"
because we've got UNIX to "port" around ;)...
C is technically a HLL but it's closer to assembly language in the terms
that C is "low-level programming" (don't be fooled by the "standard
library"...that's just "pre-written" routines for you to use...use C
_without_ that library and then you'll very quickly catch on to what I mean
:)...
The inherent "flaw" in HLL thinking, in my view, is this "concept" that the
more abstract something is, the better it is...practice does NOT confirm
this "hypothesis"...generally, the more "abstract" the language used, the
_crapper_ the software becomes (not just speed and size and resource use
but even entering "capability" and "project feasibiilty" - that's literal
"make or break" / "do or die" application territory - too...want to write
DOOM 3 with VisualBASIC any time soon? ;)...
Also, the idea that there are only one set of "abstractions" that could be
made...this is patently false too...is C better for NOT having any "string"
data type or is BASIC better for that? Depends, doesn't it? Now we have
UNICODE - which, let's not forget, is all about "portability",
"compatibility" and being "universal" about things - it's possible to
re-code a new UNICODE string library for C, no problems...because it ain't
"built in", it's easy to change...but if you want to extend a BASIC that
doesn't comprehend UNICODE in its "string" type, then how easy does that
"abstraction" make things? Oh dear, it makes it _HARDER_, it makes it
_WORSE_..."abstractions" are NOT born equally..._SOMETIMES_ something is an
"irrelevent detail", for sure...BUT NOT ALWAYS SO...HLLs make an inherent
mistake in believing they can declare certain things to always be
"irrelevent"...this is nonsense and they end up having to be "subverted" by
the compiler writers themselves to add in "extensions" and "inline ASM" and
so forth to deal with the _PRACTICAL_ fact that the "theory" simply _isn't_
good enough and it's "ideal" does NOT actually exist (nor could it
logically ever exist)...
In short, _REALITY_ is "non-portable" - tried plugging your 5.1 speakers
into a Gameboy recently? How about trying to ram an (award-winning)
Playstation joypad into one of those Nintendo "lego block" connectors or
forcing it into your PC parallel port? How exactly do you intend to _see_
your GUI on the washing machine embedded system that doesn't have any
monitor or mouse attached? - and _NO_ amount of "abstraction" can ever undo
this fundamental fact of reality itself...you can do certain things, for
sure...a "compromise" here, a "lowest common denominator" there, in order
to try to ram that square peg into the round hole...but, fundamentally,
they got it wrong...
Who's "they"? Well, whoever it was that decided to classify programming
languages as "first generation", "second generation", "third generation"
and tried to imply that they "got better" because of all the extra
"abstraction"...the people who seem to think that if they can only
"abstract" far enough, then they'll reach a point where they can type
"please, Mr.Computer, I would like for you to write Microsoft Word on my
behalf" and - ping! - the compiler does it all...people who still believe
in a false reality that we're Hopefully all wise to know doesn't actually
exist...you know, there is no "money for nothing"...when the compiler
writers turn up with hype about their "pyramid scheme", you rip up their
chain letter for the logical nonsense that it is and don't pay much
attention to it (yeah, if everyone writes 10 letters and sends $5 then each
of those people writes 10 letters and sends $5, it'll only take around 9
"generations" of this in order to receive $5 from, ooh, nearly twice the
world's entire population (hmmm, someone must be sending the letters off to
the Martians too :)...one more generation and you've got nearly 20 times
the world's population (hmmm, must send it off to the Vulcans, as well as
the Martians :) sending you $5, so you're sure to make billions from the
pyramid scheme...ummm, I think I detect a flaw in this plan! ;)...
If it sounds too good to be true, then it is too good to be
true...absolutely NO "exceptions" made for "technology"...you _KNOW_ I'm
right (not that this ever makes a single iota of difference to anything,
anyway...truth is, people don't want "right", they just want to be told
what they want to hear ;)...
> ANY clue would be greatly appreciated.
Rev. Mustard in the Living Room with the wrench? ;)
Beth :)
- Next message: Beth: "Re: wanna do something nerdy and cool?"
- Previous message: marcus: "Re: Anybody here endure C/Cpp? (.h to .inc conversion)"
- In reply to: marcus: "Anybody here endure C/Cpp? (.h to .inc conversion)"
- Next in thread: Phil Carmody: "Re: Anybody here endure C/Cpp? (.h to .inc conversion)"
- Reply: Phil Carmody: "Re: Anybody here endure C/Cpp? (.h to .inc conversion)"
- Reply: marcus: "Re: Anybody here endure C/Cpp? (.h to .inc conversion)"
- Reply: NoDot: "Re: Anybody here endure C/Cpp? (.h to .inc conversion)"
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]