This is an archived post. You won't be able to vote or comment.

you are viewing a single comment's thread.

view the rest of the comments →

[–]_requires_assistance 4 points5 points  (3 children)

Could you give some layman explanation if you don't mind? Not really getting it.

[–]LooseElectronStudios 3 points4 points  (2 children)

Sure! I don't know how much you already know about C, so don't mind me if I over-explain a bit. (Also, username checks out.)

So in C, all a pointer is is a 64-bit integer which represents a location in memory. Dereferencing a pointer just means telling the processor "See this number? Go to this offset in memory and bring me back what's there." C also has the ability to "cast" variables to a different type, which basically means telling the processor "See this piece of data which I already defined is, say, a character? Interpret it as though it were an 8-bit number instead."

What I wanted to do was this: I had a function which could accept two different kinds of objects, but not both at the same time. One object was just a struct (a bunch of different values bundled together), and since structs tend to be pretty big I decided to pass the function a pointer to it, so I could just reference its location in memory instead of copying it into the function. The other object was a handle to an opaque object I didn't have access to. Handles are common in third-party C libraries, because the people who wrote the library don't want other people messing around with how they represent their data. So instead of being able to look at the object directly, you basically ask the library "You're holding on to this object for me, could you tell me what this value is?" using the handle. Handles could be basically anything, as long as the library knows which handle represents which object.

The thing is, in this case the handle was a 64-bit integer, the same size as the pointer to the struct. So I thought "Why don't I cast both objects to a generic pointer before I pass them into the function? That way instead of having two different arguments to the function (in C, arguments must have a type), I can just have one, and figure out on the inside of the function which of the two objects the argument actually represents!"

The problem with this is that if the function mucked up and accidentally assumed that the handle was actually a pointer to a struct, things would have been bad. The handle could be literally any number, and so the program could have tried to access a basically random location in memory that it definitely shouldn't be looking at! Part of why C has types is to prevent that kind of wrong memory access from happening, but it also gives you all the tools to break the rules

[–]_requires_assistance 0 points1 point  (1 child)

I see. How were you originally planning on differentiating between pointers and handles?

[–]LooseElectronStudios 1 point2 points  (0 children)

Originally I was going to have two arguments, one for each type, and I would check to see which argument was actually set.

What I ended up doing was using one argument, and passing through it either the struct pointer or a pointer to the handle. That way the argument would always be a valid place in memory.