Search code examples
cgccmingwgetopt

getopt does not order arguments in Windows


It seems that getopt behaves differently in Windows than in Linux. Windows requires a strict ordering of parameters while in Linux I can put the arguments in any order. Consider a program test which uses getopt compiled for Linux (gcc) and Windows (MinGW) and take this command line for example:

test file1.bin file2.bin -o output.txt

Executing this command in Linux would correctly parse -o output.txt as an option(+parameter) regardless of where I put -o output.txt. It could be between file1.bin and file2.bin as well and getopt parsing would still work correctly since it sorts the arguments by putting the optional ones infront of the mandatories.

Executing this command in Windows however results in incorrect parsing, giving me a wrong index in optind variable. It seems that the exact same code when compiled in Windows does not do the sorting part for me. Why is this, can we workaround this?


Solution

  • Transferring my comments to an answer as requested.

    GNU getopt() permutes the arguments (so options can occur after non-option arguments) by default. Standard POSIX getopt() does not allow that. You can make GNU getopt() conform to POSIX by exporting the environment variable POSIXLY_CORRECT=1, or by starting the options argument with a + symbol.

    Check the manual (or source) for MinGW getopt(), or the Microsoft implementation of it. Given what you see, it probably doesn't do the permutation. However, the linked source code does support permutation — you'll need to investigate what goes on there.

    If you decide to use GNU getopt(), you'll need to get a copy of the GNU getopt() source code (maybe from GitHub getopt.c) and include it in your build process. If you use that, you'll also need ansidecl.h and getopt.h at minimum and you will need to tweak the configuration appropriately.

    Or you'll have to decide that the GNU extension of permuting options isn't portable and therefore shouldn't be used at all.