Единственным стандартным параметром является настройка optind = 1
.
Стандарт SUSv4 не упоминает optreset
и объявляет optind = 0
"не указано":
Если приложение устанавливает optind
в ноль перед вызовом getopt()
, поведение не определено.
В противном случае стандарт неясен и вообще ничего не говорит о вызове getopt()
несколько раз, ни разрешая, ни объявляя его неопределенным.
Кроме того, нет определений, которые говорят, что поддерживаются optind = 0
или optreset
(хотя первый поддерживается в OpenBSD, но не во FreeBSD, и последний в Linux / musl, но не в Linux / glib c), поэтому не может быть надежного способа обнаружить его с помощью #ifdef
s.
Не для ошибок в причудливых getopt/_long
реализациях (см. Ниже), просто установка optind = 1
для перезапуска getopt()
должна работать нормально до тех пор, пока
a) вы не используете никаких расширений GNU :
Программа, которая сканирует несколько векторов аргументов или повторно сканирует их vector более одного раза, и хочет использовать расширения GNU, такие как +
и -
в начале строки optstring, или изменяет значение POSIXLY_CORRECT
между сканированиями , должен повторно инициализировать getopt()
Сброс optind
на 0
,
b) вы не перезапустите getopt()
в середине, пока он не вернул -1
. Например. от FreeBSD getopt
:
#define BADCH (int)'?'
#define BADARG (int)':'
#define EMSG ""
...
int
getopt(int nargc, char * const nargv[], const char *ostr)
{
static char *place = EMSG; /* option letter processing */
...
if (optreset || *place == 0) { /* update scanning pointer */
optreset = 0;
...
place = EMSG;
return (-1);
...
place = EMSG;
return (-1);
...
place = EMSG;
if (strchr(ostr, '-') == NULL)
return (-1);
...
return (BADCH);
...
return (BADARG);
...
return (BADCH);
...
return (optopt); /* return option letter */
}
Ошибки
Реализация glib c getopt
будет цепляться за устаревшее состояние даже после возвращения -1
. Это может привести к глупым ошибкам и сбоям, если старые строки будут освобождены.
Реализация OpenBSD будет делать аналогично , но только при фиктивной опции -
используется, как в getopt("q", ["prog", "-q-", NULL])
. Обратите внимание, что реализация OpenBSD getopt_long
, как по умолчанию getopt()
, могла использоваться в других системах, таких как Solaris и Android.
.