Pointer Versus Global

In the basic Windows programming examples from MS, such as the ones they tout for new users of VC++ Express, they always declare a global variable for the instance handle, like this --

HINSTANCE hInst;

Petzold prefers to use a pointer, and thus does this --

1
2
3
case WM_CREATE:
   hInstance = ((LPCREATESTRUCT)lParam)->hInstance;
   return 0;


I'm really asking this because I don't understand pointers anywhere as near as well as I should.

So other than the obvious benefits that come about from confining the variable to the function, is there some additional power that the pointer possesses, i.e., something that could be done with it that could not be done with the global declaration?

I hope I'm making sense, but I've seen other code that I don't understand very well that makes much use of pointers, hence the question.
One reason for using a global variable instead of a pointer in the M$ tutorials comes about when you are multithreading. Since the stack that threads pull from is pretty small (relative to Win32 structures) and shared, even something small like a pointer could cause problems. So you want to limit the number of variables you pass to each thread. So if there is a variable that every thread should have access to, like the handle to the primary thread or an impersonated SECURITY_TOKEN structure, it makes sense to make that variable global.

Also with what Microsoft calls Job Objects (Interprocess Communication), it's "cleaner" to use global variables for important data such as each processes PROCESS_INFORMATION structure then it is to query for that data every time you need to hand off a variable or send a pause\resume command to another process.

So TL;DR I'd say parallel processing is the reason M$ encourages this behavior.
Last edited on
I hadn't thought of that, but it definitely makes sense. I think a person who knows how to use pointers well and effectively has reached a certain plateau that separates him from a introductory-level programmer, which is what I am.
Don't give up on pointers though, I can tell you for a fact that one day you'll be screwing around with a piece of code and all of a sudden it will just "click". After that you'll start useing pointers everywhere.

They're a trickey thing though, I understand them but I still mix up the Reference and Dereference operators about as often as I mix up greater then less then signs; oddly enough though I never mix up the insertion and extraction operators...
Oh, I'm not giving up on them. In fact, I do use pointers on a basic level, especially when I want to pass a simple parameter from function to another and back again, but much beyond that and I'm on shaky ground.

Also, memory is so abundant these days that it makes it almost impossible to NOT declare a bunch of global variables, at least in relatively small applications. It sure simplifies a lot of things.

Still, I think a thorough knowledge of pointers should be gained when possible. I never intend to write code for money, but I would still like to hone my craft to the highest level possible relative to all the other irons I have in the fire, which means programming is only a hobby with me.

But I sure do enjoy it.
I'm one of the crowd that uses pointers very heavily and I guess I have a somewhat different 'take' on it than ComputerGeek. I almost never write multi-threaded code (I have one app that made really good use of multi-threading to collect GPS coordinate data while other data was being keypunched in a Windows CE program), so everything ComputerGeek said above was news to me. Where I find pointers indespinsable is in the creation of custom windows controls, such as grids. I honestly wouldn't know how to create custom controls without them.

Let me pose a thought experiment for you. Take something conceptually simple, such as an edit control, i.e., text box. It just holds text, i.e., what you type into it. How do you think the character data are stored internally within Windows? Do you think that somewhere internal to Windows in the edit control's code there is some globally defined variable such as ...

TCHAR szBuffer[65536]

...and that's where your typed text goes? Well, that might work for one text box, but what if you put two on your main dialog? Or 50. What then?

The fact is, somewhere in the creation code for the text box control (and every other control too) there will be a memory allocation for space enough to hold text, and that memory will only be accessable through pointers.

I've noted that beginners often can't understand why pointers are important because the way they are always introduced in introductory texts is by showing how a variable stored in an actual variable can be minipulated through a pointer set to its address. However, the true power of pointers is the ability they give you to accomplish things when you have situations as I described above where you can't have named variables. Perhaps another way of getting at the concept is through the idea of 'instance data', i.e., dynamically allocated space for each unique instance of an object.
Now you're on to what I was originally asking, freddie1. I have some code from a very experienced programmer, and he makes HEAVEY use of pointers, so much so that I still haven't been able to decipher more than about twenty or thirty percent of what he's doing.

I know instinctively how powerful pointers can be; I just don't know programmatically how to harness that power yet. But I will, given enough time playing with them.
Here is a link to a tutorial I wrote entitles "Pointers, Dynamic Memory Allocations, And Instance Data" which might be useful...

http://www.jose.it-berater.org/smfforum/index.php?topic=1292.0

The code is all PowerBASIC but its strictly Win Api stuff as that's all I do. In there is a simple example of creating a 'label' control and it could be very, very, easily converted to C or C++ code.

Also there on my C and C++ board is a C++ example that uses pointers a lot and that is here...

http://www.jose.it-berater.org/smfforum/index.php?topic=3392.0

Another very, very powerful construct are function pointers. These seem to have been covered more in C days than in C++ nowadays. However, they are at the basis of how C++ classes are internally constructed by the compiler itself, so they are important.
Thanks for posting that, especially the second one. I'm really looking forward to going through that.
Alright, here's one of a ton of examples that I've come across, written by literally a real expert programmer, yet this program was written probably 10 or more years ago. So is this type of thing still used today --

1
2
3
4
5
6
7
typedef struct tagOWLIGHT {
   POINT   p;
   int        angle;
   double speed;
 } OWLIGHT;

typedef OWLIGHT far * LPOWLIGHT;


I'm particularly curious about the "far" declaration. Is that not obsolete?
far and near are really hangovers from the old days of 16bits and segmented memory.

You will see a lot of them though if you look through the winapi headers - but the definitions of near and far have been redefined to be blank
#define far
#define near

I suppose it was easier that way than completely redo every window api header file.

refer to the windef.h header file.
For me at least, that's pretty common yet, except for the near and far stuff, like guestgulkan mentioned.

Just the other day meesa was asking about creating his own edit control so he wouldn't have to subclass, among other things, so I posted for him some starter code for an edit control. The link is here...

http://www.cplusplus.com/forum/windows/44149/

In that you'll be able to see clearly how instance memory for a control is handled through memory allocations and pointers. Its in a dll too, and should be compilable. In the example host I just created one instance of the edit control, but for experimentation purposes, you could create a whole array of them, like for example a grid, and everything would work out fine. That's the key.
So is it fair to say that "far" and "near" are simply covered for the most part by LP (long pointer), and so on? I mean, there seems to be a lot of additional declarations since "far" and "near" have been defined to blank.
Well, strictly speaking the lp prefix is part of the same obsolete processor and memory model. It is used only by convention. Since Win95 and NT even a bit before we've been working with the flat memory model and a 32 bit address space (now 64 bit for some).
Last edited on
So is that saying that long pointers and whatnot are now primarily for backward compability?

See, I'm trying to figure where this all fits now that we are working with the flat memory model.

Have pointers pretty much gone by the wayside, or is there still a big need for them even in the flat memory model, and if so, why?
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.

Last edited on
So to directly answer your question, yes, the NEAR and FAR keywords are only for backward compatibility. When a modern 32 bit compiler pre-processes a source that includes any NEAR or FAR tokens, it simply removes them from what is actually fed into the compiler proper (just as GuestGulkan indicated). Microsoft tried pretty hard to set up the includes for 32 bit Windows (Windows 95 and Windows NT onwards) so that older 16 bit Windows code would still compile. A great deal of the ugliness in include files is caused by the desire to accomplish that.
Last edited on
I'm particularly curious about the "far" declaration.
http://www.cplusplus.com/forum/general/12435/#msg59579
Topic archived. No new replies allowed.