On Tue, Mar 23, 2021, at 22:09, Nathan Hartman wrote: > On Tue, Mar 23, 2021 at 8:39 PM Matias N. <mat...@imap.cc > <mailto:matias%40imap.cc>> wrote: > > > Hi, > > while using getopt() from a task started from NSH I realized subsequent > > calls reused the global optind and similar variables resulting in different > > results each time. I'm aware this is expected in FLAT mode and is related > > to the issue of static C++ constructors (they would only be called once, > > not every time the task is started). > > > > What I wonder is what could we do to avoid this common pitfall: > > - document it somewhere (a common issues/troubleshooting section in the > > docs would be good to have anyways) and just accept the issue > > - religiously initialize globals myself before being used (a pain, error > > prone, and a bit adhoc, working only for FLAT mode) > > > When using globals, best practice is to make it really clear that the > variables are global. Many programmers do this by prefixing global variable > names with g_*. > > I take a different approach: A long time ago, I started grouping all > globals in a struct, which has one global instance called Global. It makes > it easy to find all globals, and furthermore at the start of the program as > a matter of policy the first thing I do is memset() the Global struct to 0. > Yes, I know that is often redundant to the startup code, but in some > situations the startup code doesn't initialize globals. The FLAT model is > one example of this (from the 2nd invocation onwards). I've seen other > examples of this over the years. By memset()ing your globals at the start > of main() you can rest assured that the globals are in fact zeroed, > regardless of whatever else happened before main(). It has another side > benefit: with globals grouped this way, it becomes trivial to take a > standalone program and turn it into a component of a larger program. > tl;dr, this > approach has worked great for me for a long time.
That sounds like a good approach. > > Caveat: It won't help if your program (or any API called by it) uses > globals that are outside your control, and therefore, not initialized by > you. :-/ Yes, my concern is about functions such as getopt(). If you just follow the description of the API and use it as normal you reach this pitfall. I was looking for some approach to avoid this as much as possible. For getopt() I see there's even no standard getopt_r(), so we would have to provide our own, which may not be a bad idea. Still, this issue will probably present in many other places. > > Nathan > Best, Matias