[英]Is casting an integer value to a void* an often used paradigm in callbacks?
而不是将实际的指针发送给值,而是将值强制转换为指针。 我在GTK程序的GUI界面代码中找到了这些示例。
g_signal_connect (pastebutton[pane],
"clicked",
G_CALLBACK(on_paste_button_pressed),
(void*)((long)pane<<4));
在上面的示例中,我指的是g_signal_connect
的最后一个参数。 当GTK2调用on_paste_button_pressed
, on_paste_button_pressed
会像以下那样将user_data
空指针on_paste_button_pressed
回去:
int pane = ((long)user_data) >> 4;
实际上,我将此特定示例添加到了代码中,但是我基于已有的示例。 我添加了移位功能,以避免发出有关转换的警告。 该程序本身有四个窗格,其中包含许多小部件,复制和粘贴按钮使您可以将所有值从一个窗格复制到另一个窗格。
是否经常使用这种将值强制转换为指针地址的方式?是否有理由不应该使用此方式?
编辑:
从整数到void指针的转换也可以像这样实现:
void* void_ptr = some_int - NULL;
使用 。 当它执行所需的操作时,通常会使用它。
不使用它的原因之一是理论上指针大小可能小于源整数大小。
不使用它的另一个原因是,它仅允许您将一个整数数据传递给回调。 如果将来需要添加另一条数据(或切换到非整数),则必须找到并重写回调可以访问传递的数据的每个位置。 因此,如果将来有可能需要扩展数据,则最好创建一个struct
(即使此时仅包含一个int
)并传递一个指向该struct
的指针。
但是,如果您确定除了该单个整数外,您将永远不必传递任何其他信息,并且您的整数适合一个void *
,那么此技术就不会受到任何破坏。
PS从学上来讲,C和C ++似乎都没有整数到空*到整数转换的往返保证,即,他们不保证它可以工作并恢复原始整数值。
您应该使用宏GINT_TO_POINTER()和GPOINTER_TO_INT()在指针和整数之间进行转换。
将整数强制转换为指针可用于按值传递值。 如果您确实需要按引用参数,则这是首选方法,因为编译器随后不需要取消引用指针。
位移是一个坏主意,因为它可能导致溢出。
对于真正可移植的代码,应将intptr_t用作整数类型,因为它很适合指针。
它已被使用,但绝不是便携式的,因此您必须小心。
C标准不强制要求指针类型的位数至少应与整数类型一样多,因此您可能并不总是能够做到这一点。
但是我不记得任何 实际上指针小于整数的平台,因此您可能很安全(尽管从技术上讲不是安全的)。
我认为可以进行强制转换的唯一原因是消除了对齐警告的可能性。 C1x草案的6.3.2.3节规定:
整数可以转换为任何指针类型。 除非先前指定,否则结果是实现定义的,可能未正确对齐,可能未指向引用类型的实体,并且可能是陷阱表示。
确实可以在这种情况下使用。 它可以在许多平台上运行,但是可能会失败,因为任意整数并不总是有效的指针值,尽管您进行的移位应该可以解决这个问题。 指针也可能无法保存整数可以包含的所有值。 如果您在指针为32位的平台上使用64位long
的情况,则是这种情况,当然,由于要移动该值,即使指针和整数的大小相同,它也可能会失败。 如果要使用此技巧,则可能应该对照所使用的整数类型的大小检查sizeof (void*)
,如果指针不够大,请在运行时对照实际值进行检查。 使其完全可移植可能不值得,因此您将在需要的平台上使用实际的指针,因此要么将自己限制在可以使用此技巧的平台上,要么完全放弃该技巧。
我觉得很好。 没有有关使用频率的统计信息,但是您真的在乎吗?
不过,我不确定我是否知道移位对您有帮助。
这是来自C-FAQ:
问: 如何在指针之间转换整数? 我是否可以将整数临时填充到指针中,反之亦然?
答:曾几何时,可以保证将指针转换为整数(尽管从不知道可能需要整数还是长整数),并且可以将整数转换为指针,并且可以保证指针转换为(足够大的)整数并再次返回时保持不变,并且转换(以及任何映射)的意图是``对于那些了解机器寻址结构的人来说并不奇怪''。某些先例和对整数/指针转换的支持,但它们始终取决于机器,因此不可移植。 始终需要显式强制转换(尽管如果您忽略了早期编译器,则很少抱怨)。
为了确保C可以广泛实施,ANSI / ISO C标准削弱了这些较早的保证。 指针到整数和整数到指针的转换是实现定义的(请参阅问题11.33),并且不再保证指针可以不变地转换为整数并返回。
将指针强制为整数或将整数强制为指针从来都不是一种好习惯。 当您需要一个可以容纳任何一种数据的通用插槽时,联合是一个更好的主意。
另请参阅问题4.15、5.18和19.25。
参考:K&R1第2节。 A14.4第 210 K&R2秒 A6.6羽 199 ISO部分 6.3.4基本原理 3.3.4 H&S秒 6.2.3页 170,秒 6.2.7第171-2页
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.