The following example shows a bad example for casting pointers. The function MyFunction()
returns a 64-bit value in an OUT
parameter that is assigned from a 32-bit input parameter. There is nothing wrong with MyFunction()
. The problem is when MyFunction()
is called. Here, the address of B
, a 32-bit container, is cast to a pointer to a 64-bit container and passed to MyFunction()
. MyFunction()
writes to 64 bits starting at B
. This location happens to overwrite the value of B
and the value of A
in the calling function.
The first Print()
correctly shows the values of A
and B
. The second Print()
shows that B
was given A
's original value, but the contents of A
were destroyed and overwritten with a 0.
The cast from &B
to a (UINT64 *)
is the problem here. This code compiles without errors or warnings on both 32-bit and 64-bit processors. It executes on 32-bit and 64-bit processors with these unexpected side effects. It might also generate an alignment fault on IPF if &B
is not 64-bit aligned. One possible fix for this issue is to change B from a UINT32
to a UINT64
.
EFI_STATUSEFIAPIMyFunction (IN UINT32 ValueU32,OUT UINT64 *ValueU64){*ValueU64 = (UINT64)ValueU32;return EFI_SUCCESS;}UINT32 A;UINT32 B;​A = 0x11112222;B = 0x33334444;​//// Prints "A = 11112222 B = 33334444"//Print (L"A = %08x B = %08x\n", A, B);​MyFunction (A, (UINT64 *)(&B));​//// Prints "A = 00000000 B = 11112222"//Print (L"A = %08x B = %08x\n", A, B);