p-ranav / argparse

Argument Parser for Modern C++
MIT License
2.61k stars 242 forks source link

Odd behavior on operator= and --help argument #280

Closed Zeldax64 closed 10 months ago

Zeldax64 commented 1 year ago

The argparse presents an odd behavior on operator= and --help. Consider the following code:

#include <iostream>

#include <argparse/argparse.hpp>

auto make_parser() {
    argparse::ArgumentParser program("VoiceHD");
    program.add_argument("arg")
        .help("Description.");
    return program;
}

int main(int argc, char *argv[]) {
    argparse::ArgumentParser args;
    try {
        args = make_parser(); // Problem occurs here
        args.parse_args(argc, argv);
    } catch (const std::runtime_error& e) {
        std::cout << args << std::endl;
        std::cerr << "Failed to parse arguments! " << e.what() << std::endl;
        return -1;
    }
    return 0;
}

The program requires a positional argument. When launching it with invalid argument ./main, an exception is raised and caught, so the program finishes printing the --help message. However, when launching the program as ./main --help the program only prints "Usage:". I believe the problem occurs in the assignment operator. I'm sending the code for easy reproducibility with cmake.

cmake -B build -S .
cmake --build build
./build/main --help # Don't print help
./build/main # Print help in catch block

argparse-issue.zip

p-ranav commented 10 months ago

Thanks for the report.

Per the discussion in #260 and #226, copy and move constructors for argparse::ArgumentParser have now been deleted. You will not be able to do this (i.e., use a maker function and assign into a variable) starting from the next release.

Sorry about the inconvenience but the parser class (with its string_views, references, iterators etc.) is not written in a way that is copy-friendly. Copying the parser invalidates references and only works OK under specific cases. It is instead meant to be setup and run from a single function.