Skip to content

Getopt Notes

rail5 edited this page Feb 13, 2026 · 1 revision

Getopt Notes

XGetOpt is intentionally built on getopt_long().

This page documents the assumptions and practical implications.

Global state and thread-safety

getopt uses global variables:

  • optind: index into argv of the next element to process
  • optarg: pointer to the current option argument (if any)
  • optopt: the option character that caused an error (in some error cases)
  • opterr: controls whether getopt prints its own diagnostics

XGetOpt sets:

  • opterr = 0 (suppresses getopt printing)
  • optind = 1 (resets parsing)

And platform-specifically:

  • On GNU platforms and on Haiku, XGetOpt sets optind = 0 to fully reset the getopt state.
  • On the BSDs (such as macOS, FreeBSD), XGetOpt sets optreset = 1 to reset parsing state. This is a BSD extension.

Implications:

  • Not thread-safe: do not parse concurrently from multiple threads.
  • If your program uses getopt elsewhere, treat XGetOpt parsing as owning that state.

REQUIRE_ORDER / non-option arguments

XGetOpt enables the flag REQUIRE_ORDER by placing + as the first character in the short option string.

The result of this is that getopt stops parsing options when it encounters the first non-option argument. XGetOpt then decides how to continue based on the stop condition (see Stop Conditions and Remainders). The default behavior is to collect the given non-option argument, and then continue parsing any remaining arguments.

This is how XGetOpt collects non-option arguments into OptionSequence while still using getopt_long().

Option clustering

getopt supports clustered short options:

  • -abc is equivalent to -a -b -c

Important detail:

  • A single argv token can yield multiple getopt_long() returns.
  • optind is not required to advance for each short option returned from a cluster; it advances when getopt is ready to move past the current argv token.

This is why XGetOpt’s early-stop remainder logic captures the token index before calling getopt_long().

The -- terminator

When the special token -- is present:

  • getopt_long() treats it as “end of options”.
  • Parsing stops, and optind is positioned after the --.

In XGetOpt, all arguments after -- are treated as non-option arguments, and added to OptionSequence::getNonOptionArguments().

Error behavior

getopt_long() signals errors by returning '?' (and sometimes ':' depending on configuration; XGetOpt does not enable that mode).

Common situations:

  • Unknown option
  • Missing required argument

XGetOpt’s parse(...) throws std::runtime_error on these errors.

XGetOpt’s parse_until<BeforeFirstError>(...) stops and returns a remainder beginning at the offending token.

Portability

  • getopt_long() is available on the vast majority of platforms.
  • REQUIRE_ORDER behavior is also available on the vast majority of platforms.
  • Windows is deliberately excluded.
  • XGetOpt only guarantees compatibility within the GNU ecosystem. Support for alternative platforms is best-effort, not guaranteed.

If you need portability beyond this, consider providing an alternate backend or using a different argument parsing library.

Clone this wiki locally