The only possible use for near and far pointers would be if you were using a 16 bit compiler for DOS coding. Here is a Hello, World! program I compiled with Borland 3.1, which was a very popular DOS C and C++ compiler. I compiled this as a C program...
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
|
#include <windows.h>
#include <stdio.h>
#include <conio.h>
int main(void)
{
char szBuffer[]="Hello, World!";
char NEAR* lpBuffer;
clrscr();
lpBuffer = szBuffer;
printf("lpBuffer = %s\n", lpBuffer);
printf("lpBuffer = %u\n", lpBuffer);
getch();
return 0;
}
*/
/*
lpBuffer = Hello, World!
lpBuffer = 64456
*/
|
Here is close to the same thing using Code::Blocks on 32 bit Win XP...
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
|
#include <windows.h>
#include <stdio.h>
int main(void)
{
char szBuffer[]="Hello, World!";
char NEAR* lpBuffer;
lpBuffer = szBuffer;
printf("lpBuffer = %s\n", lpBuffer);
printf("lpBuffer = %u\n", (unsigned)lpBuffer);
getchar();
return 0;
}
/*
lpBuffer = Hello, World!
lpBuffer = 2293554
*/
|
Note in the 1st case using DOS that the address came out as 64456. Apparently, the compiler laid out the memory right near the top of its 64K window. In the 2nd case with the flat 2.1 G 32 bit memory we were able to exceed 64 K by quite a lot.
There really is a whole world of difference between these two cases and operating systems. In the 16 bit DOS case, the value of the segment selector plus the data segment offset would
have represented a real physical address on a pure DOS machine. In the Windows case all addresses are purely 'virtual', and only the operating system itself really knows where something is located in physical memory or storage. So that value above of 2,293,554 is really a memory handle. nSometimes such things are referred to as 'opaque' pointers because the operating system itself converts them to the real addresses it uses.
But the NEAR* / FAR* pointer thing has nothing to do with the justification for the use of pointers. Its purely a manifestation of the 16 bit verses 32 bit memory models of the different OSs and chips. As I mentioned earlier, I don't know how one would build a Windows Custom Control of any complexity without the use of pointers and dynamic memory allocation.
When you start doing those kinds of things though, your coding must become very, very, careful. If you acquire memory through a memory allocation, you must at some point release it or you'll have a 'memory leak'. Of course, the same thing is true of C's malloc() or the C++ new operator. The .NET Framework is predicated on the idea that the average coder isn't capable of handling memory and resources correctly. There is quite a bit of evidence this is true. So if you do hard core Win32 coding you have to be constantly striving to prove Microsoft wrong.