2017-01-02 228 views
1

如何在不写两行的情况下直接将“zend_long”赋值给“ptr”?C指针类型铸造

zend_long *val = *ptr; 
*val = *(ISC_LONG*)var->sqldata; 
+1

'ptr'的类型??? –

+0

它作为一个funstion参数:“char ** ptr” 实际上它只是一个存储缓冲区 – Marcodor

+1

除非它们是_compatible types_,否则会调用未定义的行为。 – Olaf

回答

3

假设你原来的代码是正确的,相应的分配是这样的:

*((zend_long*)*ptr) = *(ISC_LONG*)var->sqldata; 
+1

它的作品,非常感谢! – Marcodor

+0

由于严格的别名违规,这很可能会调用未定义的行为。除非'zend_long'碰巧与'ISC_LONG'类型兼容。 – Lundin

+0

@Lundin没错。这就是为什么我写道,只有原始代码是正确的,以上才有效。 – dasblinkenlight

0

指针类型转换像这些都不是C-良好定义的行为,除非这两个结构发生兼容类型。也就是说,他们必须以相同的顺序拥有相同的成员。

如果他们没有这一点,那么不幸的是没有简单的方法C.做到这一点如果你以某种方式设法得到它的“工作”,它仅仅是运气不好 - 你的代码可能随时崩溃由于未定义的行为。

这是因为这样的演员违反了所谓的strict aliasing rule。例如,您必须通过将结构包装到联合类型中来躲避该规则。

+0

感谢您提供有用的信息。我也不喜欢过度投射。但在这种情况下,这是“强制执行”的。 ISC_LONG在这里定义:https://github.com/FirebirdSQL/firebird/blob/c6d9135586fde54b52e5c26f74d5dfd20c188f3f/src/include/types_pub.h#L111和zend_long在PHP源代码中具有几乎相同的定义。所以按价值分配应该是安全的。 – Marcodor

+0

@Marcodor如果它们是相同大小的整数类型,那就很好。如果它们大小不同,或者它们是结构体,那么就会有问题。 – Lundin