I am trying to understand why use this casting style in ProcessHacker Code.
RtlSetHeapInformation(
PhHeapHandle,
HeapCompatibilityInformation,
&(ULONG){ HEAP_COMPATIBILITY_LFH }, // HEAP_COMPATIBILITY_LFH = 2UL
sizeof(ULONG)
);
What are the advantages of using "{}" for casting? Does it work in C and C++?
&(ULONG){ HEAP_COMPATIBILITY_LFH }, // HEAP_COMPATIBILITY_LFH = 2UL
This
&(ULONG){ HEAP_COMPATIBILITY_LFH },
is not a casting. It is a compound literal. It creates an object of the type ULONG
with automatic storage duration and initializes it with the value HEAP_COMPATIBILITY_LFH
. Then the address of the object is taken.
Here is a demonstrative program.
#include <stdio.h>
int main(void)
{
unsigned long *p = &( unsigned long ){ 10ul };
printf( "%lu\n", *p );
return 0;
}
The program output is
10
From the C Standard (6.5.2.5 Compound literals)
3 A postfix expression that consists of a parenthesized type name followed by a brace enclosed list of initializers is a compound literal. It provides an unnamed object whose value is given by the initializer list.
You may imagine the definition of the compound literal the following way.
For example you may initialize a scalar variable using a braced list like
unsigned long x = { 10ul };
But a compound literal has no name. So this construction
( unsigned long ){ 10ul }
in fact looks like
unsigned long unnamed_literal = { 10ul };
^ ^
| |
( unsigned long ) { 10ul }
Pay attention to that in C++ there is no such a notion as the compound literal.
(ULONG){ HEAP_COMPATIBILITY_LFH }
in C is object literal initialization.
It essentially creates an anonymous automatic (auto
, on the stack) or static (if used in a filescope compound literal) and initializes it.
(TYPE){ InitVal }
is essentially equivalent to TYPE __someInternalNameXYZ = { InitVal } /*lifted above the expression where used*/; __someInternalNameXYZ /*use*/
and it differs from casting in serveral ways.
&
on them).switch
case
s, bitfield widths or array sizes) if the casted value was an integer constant to start with but compound literal initialization never does.Compound literals are a C99 feature. They don't exist in C++ AFAIK.
In C, you can sometimes use compound literal initialization to get the gentler converting effect of C++'s static_cast
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With