Skip to main content
gamedev.net
🔒 Locked

int pointer address

Started by likeafox 11 replies 2.8k views
Original Post
likeafox
likeafox
If I were to write something like this it would compile and work just fine:

  char * var1 = "Hello";



So why can't I do something like this?:

  __int32 * var2 = &(const_cast<__int32>(0x02i32));



I tried and I get the error: 'const_cast' : cannot convert from 'const __int32' to '__int32'-- Conversion is a valid standard conversion, which can be performed implicitly or by use of static_cast, C-style cast or function-style cast It says it can't do it because it's implicit? What? Does anyone know how to get the address of an inline constant?
"It compiles! Ship it!"
DrunkenHyena
DrunkenHyena
I don't believe you can. But more importantly, why would you want to? Assign the value to a variable and make all the pointers you need.
Stay Casual,KenDrunken Hyena</FON
Simian Man
Simian Man
Quote:
Original post by likeafox
Does anyone know how to get the address of an inline constant?


I could be wrong, but isn't the point of something being *inline* so that the compiler sticks it directly into the code that uses it. So it does not even have an address at all. Why would you want to do this?
likeafox
likeafox
Quote:
Original post by Simian Man
I could be wrong, but isn't the point of something being *inline* so that the compiler sticks it directly into the code that uses it. So it does not even have an address at all. Why would you want to do this?


I figured since it was doable with strings it would certainly be doable with integers. Even if it's nested in a machine instruction, it's going to be on the stack somewhere inside the function code--

The desire to use an inline constart like this has come up more than once for me...
In this case I'm calling CreateThread which takes a void pointer parameter, for which I want to pass in an int, but I'd look a lot tidier to me if I didn't have to break it into multiple lines to start declaring variables. But I guess I'll have to if there's no way of avoiding it.
"It compiles! Ship it!"
Anon Mike
Anon Mike
Quote:
Original post by likeafox
If I were to write something like this it would compile and work just fine:
pointer to a string literal

So why can't I do something like this?:
pointer to an integer constant

Because string literals have to be stored in memory as data somewhere and integers don't. Integer constants are typically hard-coded into the instruction stream. It may also have something to do with the fact that FORTRAN did let you do stuff sort of like that and it wasn't fun when somebody went and changed the value of 5.

Got to agree with the others, it's kind of wierd that want you want to do that in the first place.
-Mike
Simian Man
Simian Man
The difference is that the value "hello" is not a string at all in a C++ program, but a pointer to the area in memory where the compiler put the string. With integers, the compiler puts them directly into the instructions - it does not store them on the stack or anywhere.

<edit>Beaten twice in one thread! [rolleyes]
LessBread
LessBread
__int32 var1 = 0x02;
__int32 * var2 = &var1
"I thought what I'd do was, I'd pretend I was one of those deaf-mutes." - the Laughing Man
Prgrmr@wrk
Prgrmr@wrk
I think this is what you want.

__int32 * var2;
*((__int32*)(&var2))= 0x02i32;

Of course, if you try to use var2 as a pointer, it will screw up. But it now contains that value. I had to do something similar to this once in a very memory tight algorithm, before I learned about unions. This is possibly the ugliest single line you can use in valid C or C++ :)
I know enough about OpenGL and game programming in general to be good at it, but not enough to always be very helpful, so I apoligize if I suggest something stupid.
LessBread
LessBread
That would make the pointer point to the address 0x00000002. Accessing that address would probably throw an exception.
"I thought what I'd do was, I'd pretend I was one of those deaf-mutes." - the Laughing Man
JohnBolton
JohnBolton
Quote:
Original post by likeafox
If I were to write something like this it would compile and work just fine:
     char * var1 = "Hello"; 
So why can't I do something like this?:
__int32 * var2 = &(const_cast<__int32>(0x02i32));
The first case is different from the second case. "Hello" is an array, which converts to a pointer automatically. It's as simple as that. BTW, some compilers don't generate an error due to const mismatch in the first case because of the all the code that would no longer compile.

Your error is due to using const_cast incorrectly. This code:
    	__int32 * var2 = &(0x02i32);
generates this error in VS 2005:
error C2101: '&' on constant
Quote:
Original post by likeafox
Does anyone know how to get the address of an inline constant?
Considering that it is not stored in memory, how could it have an address?
John BoltonLocomotive Games (THQ)Current Project: Destroy All Humans (Wii). IN STORES NOW!
Prgrmr@wrk
Prgrmr@wrk
Quote:
Original post by LessBread
That would make the pointer point to the address 0x00000002. Accessing that address would probably throw an exception.


You're absolutely right, but using the method you posted would also cause hard to debug errors if the class/function the value is passed to uses that value later on, after the original "__int32 var1" fell out of scope.

After looking closer at the CreateThread() the OP mentioned, what he should be doing is exactly what you said, except that he should just pass the address of var1 as the parameter, instead of copying that address to var2. I'm sure there's a good reason CreateThread was designed that way, but I have no idea what it is.
I know enough about OpenGL and game programming in general to be good at it, but not enough to always be very helpful, so I apoligize if I suggest something stupid.
Zahlman
Zahlman
Quote:
Original post by likeafox
it's going to be on the stack somewhere inside the function code--


No, it isn't. It could, for example, be in a register, which isn't addressable.

Quote:
In this case I'm calling CreateThread which takes a void pointer parameter, for which I want to pass in an int, but I'd look a lot tidier to me if I didn't have to break it into multiple lines to start declaring variables. But I guess I'll have to if there's no way of avoiding it.


You could make a wrapper function. The general technique is something like:

int functionWhosInterfaceWeDontLike(int* out_parameter) {  // Evil C code here}std::pair<int, int> prettyFunctionExploitingCppFeatures() {  int out_buffer;  int result = functionWhosInterfaceWeDontLike(&out_buffer);  return std::make_pair(result, out_buffer);}// or, when the input is not supposed to be modified, and the indirection// exists for a sillier reason:int functionWhosInterfaceWeDontLike(int* in_handle) {  // Evil C code here}int usingAConstReferenceLikeOneOughtToInCpp(const int& in) {  int tmp(in);  int result = functionWhosInterfaceWeDontLike(&tmp);  assert(tmp == in); // if this trips, report a bug to the API vendor  return result;}


With interfaces taking void*, though, you'll probably want to be a little more careful. (In some cases, templates are appropriate.)
LessBread
LessBread
Quote:
Original post by Prgrmr@wrk
Quote:
Original post by LessBread
That would make the pointer point to the address 0x00000002. Accessing that address would probably throw an exception.


You're absolutely right, but using the method you posted would also cause hard to debug errors if the class/function the value is passed to uses that value later on, after the original "__int32 var1" fell out of scope.

After looking closer at the CreateThread() the OP mentioned, what he should be doing is exactly what you said, except that he should just pass the address of var1 as the parameter, instead of copying that address to var2. I'm sure there's a good reason CreateThread was designed that way, but I have no idea what it is.


I didn't understand the problem when I posted that snippet. It was when I saw your "left side hack" (for lack of a better description) that I saw what the OP was going after. It seems to me that if he just wants to pass an integer value to CreateThread the solution is to simply cast the integer variable as a void pointer, pass it in and then inside the thread function recast it to a local integer variable. It seems to me that falling out of scope is not an issue if the parameter is treated as an "in" rather than an "in/out". Thinking about this a bit more, it would seem that the argument passed to the thread function resides on that thread's stack so it should be accessible until the thread function returns.

int var = 2;

CreateThread(..., (void*)var, ...);

int ThreadFunk(void *param)
{
int var = (int)param;
...
}

"I thought what I'd do was, I'd pretend I was one of those deaf-mutes." - the Laughing Man

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.