简体   繁体   中英

function pointer bit shift

I have the following code:

void (* point)();
point=prova;
unsigned long int imm8 = point<<24;

...
void prova(){
...
}

The third line of code I have error:

invalid operands to binary << (have 'void (*)()' and 'int')

I'm trying to apply the shift operator to a function pointer, but I get the following error. how can I do?

I don't see why you want to do this but the error is correct, the draft C++ standard in section 5.8 Shift operators says;

The operands shall be of integral or unscoped enumeration type and integral promotions are performed.[...]

You can use reinterpret_cast to convert it to an integral type( uintptr_t ) if needed. The linked reference contains the following example:

int i = 7;

// pointer to integer and back
uintptr_t v1 = reinterpret_cast<uintptr_t>(&i); // static_cast is an error

This type of conversion is only conditionally supported, we can see this from the C++ draft standard section 5.2.10 Reinterpret cast which says:

Converting a function pointer to an object pointer type or vice versa is conditionally-supported. The meaning of such a conversion is implementation-defined, except that if an implementation supports conversions in both directions, converting a prvalue of one type to the other type and back, possibly with different cv- qualification, shall yield the original pointer value.

There is no portable way to do this.

The standard guarantees that you can convert a void* to uintptr_t without loss of information -- but it doesn't guarantee that uintptr_t exists. A conforming implementation might not have an integer type wide enough to hold a converted pointer without loss of information.

And even if uintptr_t exists, the language only guarantees that you can convert void* to uintptr_t without loss of information. A conforming permission might have, for example, 64-bit object pointers, 64-bit uintprt_t , and 128-bit function pointers.

It's likely, in most implementations, that you can convert a function pointer to uintptr_t without loss of information. (I think POSIX guarantees this, though the ISO C and C++ standards do not.)

Once you've done that, probably using a reinterpret_cast , you have an unsigned integer, which you can shift as you like.

The result of this shift will almost certainly be meaningless garbage. C++ doesn't prevent you from shooting yourself in the foot, which is what you appear to be trying to do.

There should be no valid reason for doing this. However, you can do this by first casting to unsigned long int

unsigned long int imm8 = reinterpret_cast<unsigned long int >(point)<<24;

Here reinterpret_cast is done to treat the pointer as unsigned long int . Note that it is not portable and has the possibility of data loss.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM