Thread: Options and argument order in cli programs.

  1. #1
    Registered User
    Join Date
    May 2016
    Posts
    104

    Options and argument order in cli programs.

    Hello folks, bit of an odd question here. As far as I know Unix convention normally dictates that each program option that takes an argument should immediately be followed by that argument, e.g
    Code:
    ping -a -c 2 -i 0.5
    Many usage cases correctly display this pattern [options [option argument]] [program arguments] yet many do not; opting instead for something like:
    Code:
    usage: program [options] [program arguments]
    which isn’t entirely accurate. I realize this probably has to do with the manner in which the getopt function operates, or perhaps getopt was made to work in this manner to adhere to the established convention. Now, for better or for worse, I had to make my own getopt equivalent long ago, before I knew about this unspoken convention, and when faced with this “style” dilemma, I decided to go in another direction: Instead of
    Code:
    ./a.out -a bar -b foo
    I have
    Code:
     ./a.out -a -b bar foo # or ./a.out -ab bar foo
    or going back to my first example:
    Code:
    ping -aci 2  0.5
    I admit I went with this style in no small part because I favor the grouped options -abc much better than -a -b -c. And it felt natural and more consistent to do it that way. Recently, when reviewing a program I made, someone criticized my decision claiming it was awkward and confusing to run the program. I disagree, but now Im curious to hear what others think. Do you have any valid criticism against my approach? Thanks.

  2. #2
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    27,560
    Quote Originally Posted by Dren
    Many usage cases correctly display this pattern [options [option argument]] [program arguments] yet many do not; opting instead for something like:
    usage: program [options] [program arguments]
    which isn’t entirely accurate.
    I think the latter is accurate insofar as we regard [options] as consisting of a list of option/optional argument name/value pairs, but then it is also true that sometimes it may still be permitted for program arguments to be interspersed among the options... but then this can also be true for the former.

    Quote Originally Posted by Dren
    I admit I went with this style in no small part because I favor the grouped options -abc much better than -a -b -c. And it felt natural and more consistent to do it that way. Recently, when reviewing a program I made, someone criticized my decision claiming it was awkward and confusing to run the program. I disagree, but now Im curious to hear what others think. Do you have any valid criticism against my approach?
    I agree with the criticism: it seems to me to be more natural to have options without arguments grouped as such, and when they do have arguments, pair them with the arguments. Otherwise, there is greater room for confusion in interpretation, e.g., this looks like an option without argument followed by an option paired with an argument, followed by a program (as in positional) argument:
    Code:
    ./a.out -a -b bar foo
    These might be a bit more likely to be parsed by the reader according to your intention, but they still look like a bunch of options without arguments followed by program arguments:
    Code:
    ./a.out -ab bar foo
    ping -aci 2  0.5
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  3. #3
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    37,763
    > ./a.out -ab bar foo
    So I'm guessing that this would be the same?
    ./a.out -ba foo bar

    What if I write this by mistake?
    ./a.out -ba bar foo

    To me, this seems natural
    ./a.out -i infile -o outfile

    Whereas this seems dangerous because of the mental stack you have to keep having written -io to then remember which file is input and which is output.
    ./a.out -io infile outfile

    Easy enough with 2 args I guess, but try it with 20.
    Say gcc with lots of flags enabled.

    If I write
    ./a.out -ba bar
    Which flag complains that there is a missing parameter?

    What about optional arguments to flags?
    If both flags have optional parameters, this is clear in traditional parsing.
    ./a.out -b -a foo filename
    -b has it's default meaning
    -a has foo
    and filename is the input file.

    But in your scheme, who gets 'foo'?
    ./a.out -ba foo filename
    Do you end up with
    -b has foo
    -a has filename
    and the program reads from stdin?


    Your approach is actually harder to use in the case of creating a program to drive your program.
    Instead of incrementally adding flag value flag value to an argv, I would have to maintain a separate list of values to append to argv, once I'd finished adding flags.

    I'm curious as to how you handle filenames which begin with a minus.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  4. #4
    Registered User
    Join Date
    May 2016
    Posts
    104
    Thank you guys for the feedback.

    Although Salem brings some valid technical points, which I’ll touch later, it seems most of the issues you raise pertain to clarity and readability. After much deliberation, I have to concede on this point.

    To me, the approach is no more complicated than the established way, and it has a certain appeal from an organizational point of view. Yet this is exactly the problem; one does not write code for oneself, but for others to read. Similarly, one writes a program for others to use, and if a design choice makes this goal harder, then it is the wrong choice.

    This reminds me of a guy I knew who refused to indent his code. He would write huge squared blocks like:
    Code:
    var = functioncall();
    if (var == value)
    do something
    else dosomethingother()
    otherfunctioncall()
    which he claimed was aesthetically pleasing and helped him understand his code better.
    I felt silly thinking I’m sort of doing the same here.


    Salem,
    The idea is the program arguments would come first, then the options and anything after would be option arguments; the order in which they appear indicating the option they belong to.
    Code:
     program [program arguments] -option1 -option2 -option3 optarg1 optarg2 optarg3
    If we want to omit option2’s argument, we would need to change the position:
    Code:
     program [program arguments] -option1 -option3 -option2 optarg1 optarg3
    But as you notice, things can get unruly when the number of options increases, even I have to admit that.
    Your approach is actually harder to use in the case of creating a program to drive your program.Instead of incrementally adding flag value flag value to an argv, I would have to maintain a separate list of values to append to argv, once I'd finished adding flags.
    Very valid point.
    I'm curious as to how you handle filenames which begin with a minus.
    I actually hadn’t thought of that, why would anyone put minus at the beginning of a file is beyond me, but it is a legal character so I guess it could happen.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 4
    Last Post: 10-10-2017, 11:01 AM
  2. Template Argument inside the Argument of a Function Declaration
    By manasij7479 in forum C++ Programming
    Replies: 3
    Last Post: 06-11-2011, 05:53 AM
  3. Replies: 9
    Last Post: 04-01-2011, 04:13 PM
  4. Replies: 1
    Last Post: 05-30-2010, 10:22 PM
  5. Replies: 4
    Last Post: 03-06-2008, 03:38 PM

Tags for this Thread