Having a header that defines some static inline
function that contains static
variables in it, how to achieve merging of identical static local variables across all TUs that comprise final loadable module?. In a less abstract way:
/* * inc.h */#include <stdlib.h>/* * This function must be provided via header. No extra .c source * is allowed for its definition. */static inline void* getPtr() { static void* p; if (!p) { p = malloc(16); } return p;}/* * 1.c */#include "inc.h"void* foo1() { return getPtr();}void* bar1() { return getPtr();}/* * 2.c */#include "inc.h"void* foo2() { return getPtr();}void* bar2() { return getPtr();}
Platform is Linux, and this file set is built via:
$ clang -O2 -fPIC -shared 1.c 2.c
It is quite expected that both TUs receive own copies of getPtr.p
. Though inside each TU getPtr.p
is shared across all getPtr()
instantiations. This can be confirmed by inspecting final loadable binary:
$ readelf -s --wide a.out | grep getPtr 32: 0000000000201030 8 OBJECT LOCAL DEFAULT 21 getPtr.p 34: 0000000000201038 8 OBJECT LOCAL DEFAULT 21 getPtr.p
At the same time I'm looking for a way of how to share getPtr.p
across separate TU boundary. This vaguely resembles what happens with C++ template instantiations. And likely GRP_COMDAT
would help me but I was not able to find any info about how to label my static var to be put into COMDAT.
Is there any attribute or other source-level (not a compiler option) way to achieve merging such objects?