Usually C, unlike dynamic languages, considered not so easy to write context sensitive code.
To demonstrate that this is feasible, at least on some systems and compilers I wrote following hack.
Function
foxy()
behaves differently depending on
who called it. This behavior could be useful in profilers,
and some modularity checks (for example if you want to ensure noone calls your static functions even by pointers).#include <elf.h> #include <stdio.h> #include <stdint.h> typedef struct { intptr_t start; intptr_t end; char* value; } range_t; static range_t ranges[2]; int compute_size(void* start) { Dl_info dlip; Elf32_Sym* sym = 0; int rv = dladdr1(start, &dlip, (void**)&sym, RTLD_DL_SYMENT); return (rv && sym) ? sym->st_size : -1; } void init_ranges() { int i; ranges[0].start = (intptr_t)&foo; ranges[0].value = "foo"; ranges[1].start = (intptr_t)&bar; ranges[1].value = "bar"; for (i=0; i < sizeof(ranges)/sizeof(ranges[0]); i++) { int sz = compute_size((void*)ranges[i].start); if (sz < 0) { sz = 0; } ranges[i].end = ranges[i].start + sz; } } char* foxy() { intptr_t caller = (intptr_t)__builtin_return_address (0); int i, idx = -1; for (i=0; i < sizeof(ranges)/sizeof(ranges[0]); i++) { if (caller >= ranges[i].start && caller < ranges[i].end) { idx = i; break; } } if (idx != -1) { return ranges[i].value; } return "other"; } void foo() { printf("foo=%s\n", foxy()); } void bar() { printf("bar=%s\n", foxy()); } void boo() { printf("boo=%s\n", foxy()); } int main() { init_ranges(); foo(); bar(); boo(); return 0; }