Edit:Apparently accessing variables inside braced groups after they end is undefined behaviour. Since I don't want to use dynamic allocation for nodes (as suggested by @dbush, @ikegami) I assume the next best way to keep hidden variables (within a function) is generating unique variable names for the nodes (with __LINE__
) and 'declaring' without the use of a braced group. The code now reads something like
#define PASTE_(x, y) x ## y#define PASTE(x, y) PASTE_(x, y)#define LT_mark_(LABEL, NAME, DELETE)\ struct LifeTime LABEL ={\ .delete=DELETE,\ .prev=lt_head,\ .ref=NAME\ };\ \ lt_head = &LABEL;\#define LT_mark(NAME, DELETE) LT_mark_(PASTE(lt_, __LINE__), NAME, DELETE)
/Edit
I'm trying to keep records for memory allocated within a function's scope. Records are kept by a LifeTime
structure, which form a linked list. This list is later traversed when returning from said function, in order to automatically free the memory. The lt_head
variable is used to keep track of the current head of the list.
struct LifeTime { void (*delete)(void*); struct LifeTime *prev; void *ref;};#define LT_mark(NAME, DELETE)\ {\ struct LifeTime _ ={\ .delete=DELETE,\ .prev=lt_head,\ .ref=NAME\ };\ \ lt_head = &_;\ }int example (){ struct LifeTime *lt_head = NULL; char *s = malloc(64); LT_mark(s, free); char *s2 = malloc(64); LT_mark(s2, free); ...}
Using this code, the temporary variables (named _
) within the braced groups created by the LT_mark
macro, are created with the same memory address.
I assume the reason for this is, as stated in the answer to this question: In C, do braces act as a stack frame?that variables with non-overlapping usage lifetimes may be merged if the compiler deems it appropriate.
Is there any way to override this behaviour? I acknowledge it may be impossible (I am using GCC without any optimization flags, so I can't simply remove them), but the actual code I am working with requires that the variables inside these groups are kept afterwards, though hidden from visibility (as braced groups do usually). I considered using __attribute__((used))
but apparently this is only valid for functions and global variables.