On Tue, Mar 23, 2021 at 8:39 PM Matias N. <mat...@imap.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. 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. :-/ Nathan