char *argv[] = {"my-program", "--config-file", config_file, NULL};
run_command(argv);
With only `--config-file=x`, you would have to allocate memory for the option: char *config_file_opt = asprintf("--config-file=%s", config_file);
char *argv[] = {"my-program", config_file_opt, NULL};
run_command(argv);
free(config_file_opt);
And it becomes even more hairy if you A) want to avoid heap allocation in most cases or B) want to use standard functions rather than asprintf. You'd have to do something like this: char config_file_opt_buf[1024];
char *config_file_opt;
size_t config_file_opt_len = snprintf(config_file_opt_buf, sizeof(config_file_opt_buf), "--config-file=%s", config_file);
if (config_file_opt_len >= sizeof(config_file_opt_buf)) {
config_file_opt = malloc(config_file_opt_len);
snprintf(config_file_opt, config_file_opt_len, "--config-file=%s", config_file);
} else {
config_file_opt = config_file_opt_buf;
}
char *argv[] = {"my-program", config_file_opt, NULL};
run_command(argv);
if (config_file_opt != config_file_opt_buf) {
free(config_file_opt);
}
And even that ignores any kind of error checking of snprintf or malloc which may fail. I also wouldn't even be comfortable assuming the code I just wrote is correct, without thinking long and hard about it and reading standards/documentation thoroughly. Whereas the first example is so simple it's obviously correct.I think we should keep `--long x`. If anything, `--long=x` is the one which should go. There will always be ambiguity; the meaning of something like `-ab` also depends on whether `-a` takes an argument or not.
Really though, I think there are enough situations where `--long=x` is useful that I think keeping both versions makes sense.
If you're that worried about performance about a few string allocations, you shouldn't be passing around strings anyway, shell or not.. And simply call functions from the same process and use for example the file descriptors you already have.
You could also just simply pass a binary blob (messagepack) as one of the arguments, if that's your thing.
The fact that this is cumbersome in C is fixed by fixing C, not by forcing a pattern onto the ecosystem that only makes sense to work around C's deficiencies.
The argument that you should just heap-allocate because it usually doesn't matter in contexts where you'd spawn a process anyways is a much better argument though. Still, I find the `{"whatever", "--config-file", config_file}` approach much more elegant.
For example, someone might write:
args = [cmd, f'--foo="{foo}"']
and expect the surrounding quotes to be stripped off, but that'll only happen if the spawn goes through a shell first. Some argument parsers may also try to strip quotes off, but I don't believe there's any consistent behavior guaranteed around that.Just wondering: why `--long=x` over `--long x`?
It only lacks in being able to work with brace expansion to facilitate specifying multiple values.
--long={foo,bar}
becomes
--long=foo --long=bar
--option{X,Y} -> --optionX --optionY
--option:{X,Y} -> --option:X --option:Y
...For the problem you mention, I normally have them separate while I use completions, then add the = sign after.