1

How to cast "ptr" to assign directly a zend_long into it without writing two lines?

zend_long *val = *ptr;
*val = *(ISC_LONG*)var->sqldata;
5
  • it comes as a funstion argument as: "char **ptr" in fact it is just a storrage buffer Commented Jan 2, 2017 at 11:57
  • 1
    Unless they are compatible types, this invokes undefined behaviour. Commented Jan 2, 2017 at 12:13
  • Why can't you write 2 lines? Too readable? Commented Jan 2, 2017 at 14:43
  • @Lundin, i think it will not allocate a local variable if i'll using cast on the fly Commented Jan 2, 2017 at 17:37
  • @Marcodor Whether or not local variables are allocated has nothing to do with the amount of lines or the presence/absence of programmer-declared variables. Either the results need to be stored at a temporary location or they don't - the compiler will/won't generate machine code for that regardless of what variables we do or don't declare in the C source. In this case the compiler will optimize away the local variable. It is generally good programming practice to split complex instructions into several lines by using temporary variables. Commented Jan 3, 2017 at 7:46

2 Answers 2

3

Assuming that your original code is correct, the corresponding assignment looks like this:

*((zend_long*)*ptr) = *(ISC_LONG*)var->sqldata;
Sign up to request clarification or add additional context in comments.

2 Comments

This will most likely invoke undefined behavior because of strict aliasing violation. Unless zend_long happens to be type compatible with ISC_LONG.
@Lundin That's right. This is why I wrote that the above will work only if the original code is correct.
0

Pointer casts like these are not well-defined behavior in C, unless the two structs happen to be compatible types. That is, they have to have identical members in identical order.

If they don't have that, then there is unfortunately no easy way to do this in C. If you somehow managed to get it to "work" it is merely out of luck - your code could crash at any time because of undefined behavior.

This is because such casts violate the so-called strict aliasing rule. You will have to dodge that rule by for example wrapping the structs inside a union type.

2 Comments

Thanks for useful info. I don't like over-casting too. But this is "enforced" in this case. ISC_LONG defined here: github.com/FirebirdSQL/firebird/blob/… and zend_long have almost the same definition in PHP source. So assigning by value should be safe.
@Marcodor If they are integer types of the same size you are fine. If they are of different sizes, or if they are structs, you would have problems.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.