Boost logo

Boost :

From: Jason Stewart (res0054p_at_[hidden])
Date: 2002-01-24 09:47:42


> > bool set(const string& name, const string& value)
> > {
> > // NB not thread-safe, need lock here
> > static std::map<string, string> m_strings;
> >
> > m_strings[name] = name + '=' + value;
> > putenv(m_strings[name].c_str());
> > return true;
> > }
>
>What purpose is served by m_strings ? It seems to be a write-only
>map. Furthermore, using m_strings[name] to get back a string you
>had only one statement earlier is rather expensive.

There are two problems with putenv. The easiest one to deal with is that it
requires the string in the form of "name=value". Secondly, it stores the
pointer that you pass to it. In the example above value may be a temporary
created just for this function call. Thus putenv(value.c_str()) followed
later by a getenv("name") will at best crash, at worst return garbage since
value has gone out of scope and its memory freed. To make matters worse,
you can't allocate memory (with strdup or something similar) because if the
user calls putenv again the pointer is replaced by the new one and
delete/free is never called.

By putting the strings in the map you can be assured that they not only
stay around but are cleaned up when your program exits. However, you must
call putenv with the string in the map since it will make a copy of the
your temporary. Your concern with speed could be addressed by using insert
which would return an iterator to the one inserted.
> but then you'd need another call (and function) to determine whether
> > an environment variable was set at all, and to define some sensible
> > behaviour when trying to access a non-existent variable, or when the
> > conversion from string fails (throwing an exception I think is
> > overkill, so I suppose setting an error state is the only other
> > possibility).
>
>I'm not sure you'd have to choose. You could have both interfaces, and
>have [] throw if the variable isn't found . That seems entirely reasonable.

I think this is OK but I still argue in favor of an interface that returns
a default if the requested variable is not found. To me, this simplifies so
much code that it is worth the extra function.

Jason


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk