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.