> 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.

Here is the one we have been using.

https://github.com/PX4/PX4-Autopilot/commit/eab32572f42f8e3e715b952512b6f5
df9041f848

https://github.com/PX4/PX4-Autopilot/blob/master/platforms/common/px4_geto
pt.c


David

-----Original Message-----
From: Matias N. [mailto:mat...@imap.cc]
Sent: Tuesday, March 23, 2021 6:18 PM
To: dev@nuttx.apache.org
Subject: Re: avoiding pitfal of reuse of globals in FLAT mode?



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

Reply via email to