【问题标题】:function pointer bit shift函数指针位移
【发布时间】:2014-06-03 15:12:46
【问题描述】:

我有以下代码:

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

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

第三行代码我有错误:

二进制的无效操作数

我正在尝试将移位运算符应用于函数指针,但出现以下错误。我该怎么办?

【问题讨论】:

  • 为什么要对指向函数的指针进行位移?
  • 您不能对指针进行位移。这甚至没有意义。如果您必须生活危险,请将指针投射到uintptr_t。
  • 显然您并不完全了解您在这里尝试的内容。现在是你解释你提出这个问题的动机的时候了。
  • @pask 我同意其他人的观点。虽然我提供了一个可行的解决方案,但您仍然需要说明为什么您正在做您正在做的事情。尽管这里似乎有一个巨魔对所有实际答案投了反对票,但您仍然需要在此处声明您想要实现的确切目标。
  • 我必须同意编辑您的问题以解释您的目标会有所帮助。

标签: c++ function-pointers


【解决方案1】:

我不明白您为什么要这样做,但错误是正确的,5.8 部分中的 C++ 标准草案 Shift 运算符 说;

操作数应为整数或非范围枚举类型,并执行整数提升。[...]

如果需要,您可以使用reinterpret_cast 将其转换为整数类型(uintptr_t)。链接参考包含以下示例:

int i = 7;

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

警告

这种类型的转换只是有条件地支持,我们可以从 C++ 草案标准部分 5.2.10Reinterpret cast 中看到:

将函数指针转换为对象指针类型,反之亦然 有条件地支持。这种转换的意义是 实现定义,除非实现支持 双向转换,将一种类型的纯右值转换为 另一种类型和背面,可能具有不同的 cv- 限定, 应产生原始指针值。

【讨论】:

  • 无法保证您可以将函数指针转换为uintptr_t 而不会丢失信息。 (void*有这样的保证。)
  • @KeithThompson 感谢您的评论,我现在看到它是有条件的支持。让我添加标准报价。
【解决方案2】:

没有可移植的方式来做到这一点。

该标准保证您可以将void* 转换为uintptr_t 而不会丢失信息——但它不保证uintptr_t 存在。符合规范的实现可能没有足够宽的整数类型来保存转换后的指针而不会丢失信息。

即使uintptr_t 存在,该语言也只保证您可以将void* 转换为uintptr_t 而不会丢失信息。例如,符合要求的权限可能具有 64 位对象指针、64 位 uintprt_t 和 128 位函数指针。

在大多数实现中,您可能可以将函数指针转换为uintptr_t 而不会丢失信息。 (我认为 POSIX 可以保证这一点,尽管 ISO C 和 C++ 标准没有。)

一旦你这样做了,可能使用reinterpret_cast,你就有了一个无符号整数,你可以随意移动它。

这种转变的结果几乎肯定是毫无意义的垃圾。 C++ 不会阻止你在自己的脚下开枪,这似乎是你正在尝试做的。

【讨论】:

    【解决方案3】:

    应该没有有效理由这样做。但是,您可以先转换为 unsigned long int

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

    这里reinterpret_cast 完成将指针视为unsigned long int。请注意,它不可移植,并且有可能丢失数据。

    【讨论】:

    • 你怎么知道unsigned long int 可以保存转换后的函数指针而不丢失信息?
    • @pask,每个答案都是关于 c++ 的。但是在C 中,您可以只转换为适当的类型unsigned long int imm8 = (unsigned long int)point&lt;&lt;24;。但与 C++ 一样,任何事情都可能发生
    • @pask 如果你有 C 源代码,你到底为什么要标记这个 C++?
    猜你喜欢
    • 2010-12-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-12-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多