ABOUT CALLBACK ("pascal") in MFC
"CALLBACK" is defined as __stdcall, not "far pascal". It
hasn't been defined as "far pascal" since the 16-bit versions of
Windows. In fact, "pascal" does not exist except as an artifact of
some unrevised documentation and a couple unrevised header files.
However, "PASCAL" is defined as "__stdcall", which is thus equivalent
to CALLBACK.
The _pascal keyword in the 16-bit compilers indeed changed the order of the
parameters on the stack. It also changed the order of side effects,
for example, if I had two functions:
void A(int a, int b)// default linkage, normally cdecl
void _pascal B(int a, int b)
then if I called them as
A(i++, i);
B(i++, i)
I got A(3, 3) but B(3, 4). This had the implication that if I changed
the default linkage from C to Pascal the meaning of my program could
change. The __stdcall linkage pushes (and consequently evaluates)
arguments right-to-left, the same as the __cdecl linkage.
Many years ago, Microsoft actually sold a Pascal compiler. The Pascal
language required that arguments be evaluated left-to-right, and
consequently that was how the compiler evaluated, and pushed, its
arguments. Since the Pascal language did not support variable-length
argument lists (except in a couple special functions known to the
compiler), the Pascal compiler could exploit the fact that the
hardware has a single instruction that can return and clear the
parameters from the stack.
When Windows 1.0 was created, the 4K page size was horribly visible to
the programmer and the OS. The goal was to make programs as small as
possible, and the Pascal linkage saved one instruction on each call.
This Was Good. So the Pascal linkage was adopted. Hence the name.
Because __cdecl cleans up the stack at the call site, it can call a
function with a variable number of arguments. Like the old pascal
linkage, __stdcall lets the called function clean up the stack.
thanks joe
Actually, PASCAL pushes arguments right to left, just like C. This is because PASCAL is
just a synonym for __stdcall. In Win16, it pushed the arguments in the opposite order,
which meant that you could change the meaning of a program by doing a
compile-with-default-linkage-type-pascal if evaluating the arguments had side effects.
That was removed in Win32, and the vestigial keyword PASCAL was simply defined to be
__stdcall, and __stdcall and __cdecl both push right-to-left. In spite of the fact it is
obsolete, it still appears in source code and documentation. I regularly point out the
flaws in the documentation, but that seems to have no effect.