An option which partially matches multiple getopt long options doesn't produce an error. Reproducer: #include <stdio.h> #include <getopt.h> int main(void) { const char *argv[] = {"a", "--f", "b", NULL }; int index, c; static struct option long_options[] = { {"foobar", required_argument, 0, 0}, {"foobaz", required_argument, 0, 0}, {0, 0, 0, 0} }; c = getopt_long(3, (char **)argv, "", long_options, &index); printf("c=%d index=%d\n", c, index); } Actual result: c=0 index=0 Expected result: option '--f' is ambiguous; possibilities: '--foobar' '--foobaz' c=63 index=0 More information: It seems this doesn't happen when the two options are different in the required_argument vs no_argument setting. Observed on Fedora 34 using glibc-2.33-16.fc34.x86_64.
That's not a bug. The two options are exactly equivalent, so there is no ambiguity.
They are not equivalent. They have a different index, which is how the application where I came across this issue recognizes them.
You need to use a different val.
Ok, if you don't plan to fix this issue, it would be good to have it described in the getopt_long() man page, or at least fix the example it contains to not use the same val for different options, so new projects are less likely to fall into this trap. I'll see if I can submit a patch for the man pages.
FWIW, the getopt code checks also for a different flag, not just val and has_arg. A minimal workaround, at least when the struct config is not reallocated, is to point the flag to the val itself, e.g. opts[i].flag = &opts[i].val;