[RFC] Make getenv O(1)

Rich Felker dalias@aerifal.cx
Mon Oct 21 18:05:00 GMT 2013


On Mon, Oct 21, 2013 at 09:26:32PM +0400, Alexander Monakov wrote:
> 
> 
> On Mon, 21 Oct 2013, Ondřej Bílka wrote:
> 
> > On Mon, Oct 21, 2013 at 08:55:37PM +0400, Alexander Monakov wrote:
> > > On Mon, 21 Oct 2013, Ondřej Bílka wrote:
> > > > Why, following does not need synchronization.
> > > > 
> > > > #define GETENV(x) ({ \
> > > >   static char *__ret = NULL; \
> > > >   if (__builtin_constant_p (x) && !__cached) \
> > > >     __ret = getenv (x) + 1; \
> > > >   __builtin_constant_p (x) ? __ret - 1: getenv (x);})
> > > 
> > > This wouldn't compile as __cached is not defined (and I'll admit I don't see
> > > what approach you're trying to convey).
> > > 
> > s/__cached/__ret/ 
> 
> Ah, my bad.  While this would be ok in practice, I think incrementing a
> pointer containing a NULL value invokes undefined behavior, doesn't it?

It does. So does unsynchronized access to an object, even if you think
it's harmless like in this case. If you only care about the null UB,
you could however just use the address of a "static const char
__sentinel" instead of NULL as the flag for uninitialized. But I think
it's best to simply write this with clean, correct use of
synchronization rather than ugly hacks.

Rich



More information about the Libc-alpha mailing list