martinmoene / span-lite

span lite - A C++20-like span for C++98, C++11 and later in a single-file header-only library
Boost Software License 1.0
494 stars 40 forks source link

remove dependencies on string, #19

Closed nolange closed 6 years ago

nolange commented 6 years ago

Add a new config MEMBER_AT_REPORTS_DETAIL, disabled by default. Enabling this config option will result in extended messages for out-of-bounds access

should be portable aslong index_t is signed and not bigger than a longlong

see #16

martinmoene commented 6 years ago

@nolange Thanks for your help. Instead of introducing span_CONFIG_MEMBER_AT_REPORTS_DETAIL I've chosen to control this via span_FEATURE_MEMBER_AT's value. I'm also using long instead of long long for non-MSVC pre-C++11 compilers.

nolange commented 6 years ago

Thanks for fixing this that fast. One question though: did you try just using sprintf? AFAIK, old (MS) compilers don't have snprintf and newer one have a specialization to automatically use a similar function if the the first argument to sprintf is an array.

(I had to mess with workarounds because I used a pointer)

should I close this PR?

martinmoene commented 6 years ago

One question though: did you try just using sprintf?

It did cross my mind. As the format specifier must adapt based on the availability of %lli (and may have to downgrade to %li) anyway, I thought it acceptable to also differentiate between the various guises of printf().

If you're happy with the result the PR can be closed.

@nolange , thanks a lot for bringing this up (the dragging of heavy dependencies) and help solve it!


In the past I have done embedded programming in x6805 assembly, more recently in C++ on Arduino to support my son with a school project and I'm (somewhat) keen to support embedded use of the lite libraries.

nolange commented 6 years ago

As the format specifier must adapt based on the availability of %lli ...

that's completely irrelevant for choosing between s[n]printf, any C99 capable system/clibrary needs to support it. The only unkown is MSVC, there aint any docs online anymore before VS2010, but I believe they supported this specifier for decades.

the only argument against using sprintf would be if some compiler goes crazy with warnings.

martinmoene commented 6 years ago

I've now approached long long as a C++11 type and g++ -std=c++98 does complain when using long long. Downto MSVC 8 (VS2005) there's no problem.

What I meant to say:

As it already isn't just

    char buffer[ 2 * 20 + sizeof fmt ];
    sprintf(buffer, sizeof buffer, "span::at(): index '%lli' is out of range [0..%lli)", static_cast<long long>(idx), static_cast<long long>(size) );
")

because I have to take extra steps for differentiating something (the format specifier), I can as well differentiate between the various functions.

Perhaps I should favour the route with long long, suppressing the warnings and then on the suppressing path simply use sprintf(). I'll look at it again :)