Sign in to follow this  
likeafox

int pointer address

Recommended Posts

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?

Share this post


Link to post
Share on other sites
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?

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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]

Share this post


Link to post
Share on other sites
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++ :)

Share this post


Link to post
Share on other sites
That would make the pointer point to the address 0x00000002. Accessing that address would probably throw an exception.

Share this post


Link to post
Share on other sites
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?

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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.)

Share this post


Link to post
Share on other sites
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;
...
}

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this