I want to put the back and forth under @Bathsheba's post to rest. So here's an answer about the finer details of what you are doing.
@Sean already suggested you reinterpret_cast your pointers instead. And that is equivalent to your second chain of casts. It says as much in [expr.reinterpret.cast]/7:
An object pointer can be explicitly converted to an object pointer of a different type. When a prvalue v of object pointer type is converted to the object pointer type “pointer to cv T”, the result is static_cast<cv T*>(static_cast<cv void*>(v)). [ Note: Converting a prvalue of type “pointer to T1” to the type “pointer to T2” (where T1 and T2 are object types and where the alignment requirements of T2 are no stricter than those of T1) and back to its original type yields the original pointer value. — end note ]
Now, let's examine each step of the two step conversion. First we have a static_cast<void*>. According to [conv.ptr]/2 (emphasis mine):
A prvalue of type “pointer to cv T”, where T is an object type, can be converted to a prvalue of type “pointer to cv void”. The pointer value is unchanged by this conversion.
The first conversion doesn't do any alteration to the address. And then it also says in [basic.compound]/5:
A pointer to cv-qualified or cv-unqualified void can be used to point to objects of unknown type. Such a pointer shall be able to hold any object pointer. An object of type cv void* shall have the same representation and alignment requirements as cv char*.
So a char* may store any address a void* may store. Now it doesn't mean the conversion from void* to char* is value preserving, only that they can represent the same values. Now, assuming a very restricted use case, that is enough of a guarantee. But there's more at [expr.static.cast]/13:
A prvalue of type “pointer to cv1 void” can be converted to a prvalue of type “pointer to cv2 T”, where T is an object type and cv2 is the same cv-qualification as, or greater cv-qualification than, cv1. If the original pointer value represents the address A of a byte in memory and A does not satisfy the alignment requirement of T, then the resulting pointer value is unspecified. Otherwise, if the original pointer value points to an object a, and there is an object b of type T (ignoring cv-qualification) that is pointer-interconvertible with a, the result is a pointer to b. Otherwise, the pointer value is unchanged by the conversion.
Where am I going with this? Assuming pc already holds the address of an int (suitably converted according to the above), then casting the char* to an int* via reinterpret_cast will give you the address of the original int. The note under the first paragraph says as much, and the further quotes prove it. If it doesn't hold the address of an int, you are playing roulette and are likely going to lose. Your program has undefined behavior. You should follow Bathsheba's advice to the letter.
(int*)pcis short, but it hides a hefty conversion. Your compiler is most probably warning you so you aren't caught off guard. When you spell the conversions explicitly, it just assumes you know what you are doing.int*to achar*not the other way round.reinterpret_castof pointer types is the same asstatic_castviavoid*, and how you can't often do anything useful with the resulting pointer anyway. Sure, there are a specific subset of legitimate cases for it, but there's no evidence from your toy example that you have such a case. And without an explanation of what you're trying to do, not just how you're currently trying to do it, such questions might be doomed to quibbling about the how instead of solving the what :P