On Sat, Jul 31, 2021 at 3:33 PM Jon Steinhart <jon@fourwinds.com> wrote:
Richard Salz writes:
> On Sat, Jul 31, 2021 at 3:21 PM Jon Steinhart <jon@fourwinds.com> wrote:
>
> > opinion, it doesn't add value to do something that's already been done
> > but differently; it detracts from value because now there's yet another
> > competing way to do something.
> >
>
> You mean like not using getopt and rolling your own?  Shrug.
>
> while ((i = getopt(argc, argv, "xxxxx:xxxx")) != -1)
>    switch (i) {
>    case ....
>   }
> argc -= optind;
> argv += optind;
>
> So I never got getopt().  One of my rules is that I don't use a library
> > in cases where the number of lines of gunk that that it takes to use a
> > library function is >= the number of lines to just write it myself.
>
>
> I don't know, what lines in the above are extra beyond what you write?  The
> last two if being generous I suppose.

Well, in my opinion that's not really an accurate representation of using getopt.

I would of course write the #include line, and the table of options, which would
end up being >= the number of lines that it takes me to do this...

        while (--argc > 0) {
                if (*(++argv)[0] == '-') {
                        for (p = *argv + 1; *p != '\0'; p++) {
                                switch (*p) {

Except for all the things this gets wrong, it's ok. The problem with inlining getopt
is that you wind up with cases like -f foo'' on the command line being treated differently
than '-ffoo'. Inlined code like this can be quite frustrating for the user to use. Your
locality of reference is cut and paste bugs that getopt eliminates because it handles
all the special cases in a uniform way.
 
Even if it took a few more lines to do it my way, I'm a believer that good coding
style keeps "meatspace locality of reference" in mind.  As programmers, we put in
a lot of effort to ensure locality of reference for computers, but then completely
toss it for people who aren't as good as it.  So given a choice of a few lines of
code versus having to look something up somewhere else, I choose the few lines of
code.

And a few more bugs...

Being a geezer, I have lots of code lying around from which I can extract working
fragments such as the one above.  Writing those few lines of code provides insulation
from supply-side attack vectors bugs in libraries, versioning issues, having to load
debug libraries, and so on.

getopt has been standardized since the 80s and has had universal adoption since
the 90s. Hardly a version chasing issue since it's in everybody's libc.
 
I realize that this isn't a huge deal by itself; it's a philosophical point.  When
I strace any random program that I didn't write I'm astonished by the amount of
library loading that takes place.  So any issues are multiplied by n.

The flip side to this is that libraries can be debugged once, while inline code
like the above needs to be deugged over and over....
 
Don't get me wrong; I use plenty of libraries.  But I tend to use those for stuff
that is so common that there is a benefit from shared libraries (or at least there
was before everything got containerized) and for libraries that do actual hard stuff.
But I don't use libraries for small snippets of code that I could easily write
myself yielding better code clarity for others reading my code.

Given the number of times I've been burned by trying to roll my own getopt,
I stopped trying years ago. It's harder than it looks.

Warner
 
Jon