Using CppCoreGuidelines gsl::string_span to ease main() argument handling


#1

Working in a bit of CppCoreGuidelines into a command line project. Old friends argc/argv might be a good opportunity to use the non-owning view gsl::string_span, thus dodging c-style zero-terminated char arrays.

Here’s what I came up with:

#include "gsl-lite.h" // using martin moene's c++11 more compatible version

//==============================================================================
/** Turn c-style standard main arguments into vector of non-owning string_spans.
    
    Does not capture argv[0] i.e. the executable path/filename!
    (If you need this just modify to count from i = 0!)
*/
std::vector<gsl::string_span> makeArgumentsVector (int argc, char* argv[])
{
    std::vector<gsl::string_span> arguments;
    for (int i = 1; i < argc; ++i)
        arguments.push_back (gsl::string_span {argv[i]});

    return arguments;
}

//==============================================================================
int main (int argc, char* argv[])
try
{
    auto arguments = makeArgumentsVector (argc, argv);

    if (arguments.empty())
        throw std::runtime_error ("No arguments given to executable!");
        // or assert, or whatever your error policy is.
    else
    {
        for (auto argument : arguments)
        {
            // lets say loadWavFile() expects a char*,
            // so to get this back, call .data()
            auto wav = loadWavFile (argument.data());

            //... do something with wav
        }
    }
    return 0;
}
catch //... snip!

P.S. Martin Moene’s version of GSL is C++98/C++11 compatible, and single header. It’s worked for me so far.


#2

I’m a big fan of the GSL idea and classes, but if you’re using juce then in this case a StringArray would make for much tighter, more readable code, e.g.

StringArray makeArgumentsArray (int argc, char* argv[])
{
    return { (const char**) argv + 1, argc - 1 };
}

The only advantage of a string_span would be to save a few bytes + a few nanoseconds of overhead in not making copies. (But you’d probably end up turning most of the arguments into Strings later on anyway to do more complex operations with them than a string_span provides)


#3

Aha! That’s very clean and simple for JUCE projects.

Sometimes when you’re playing with a new toy you forget about your old toys :slight_smile: