c42f / tinyformat

Minimal, type safe printf replacement library for C++
531 stars 75 forks source link

Why only 16 parameters instead of 32, 64, 128? #61

Closed evandrocoan closed 4 years ago

evandrocoan commented 4 years ago

https://github.com/c42f/tinyformat/blob/705e3f4e1de922069bf715746d35bd2364b1f98f/tinyformat.h#L392

c42f commented 4 years ago

Because simulating variadic templates in C++98 will always inherently be a hack and we've got to stop somewhere. If you want, you can set maxParams to something larger and rerun the code generator yourself.

Even better, just use tinyformat in C++11 mode and this limitation is not relevant.

evandrocoan commented 4 years ago

I have to use C++98 because I work with a legacy system. I just hit the 16 limit value. By default, it could be 32, which is not so easy to hit.

I would not call this a hack, it just automatically define 16 functions and C++ correctly selects between them.

evandrocoan commented 4 years ago

Unless 32 functions significantly increases the compiling time.

c42f commented 4 years ago

I guess we could increase the limit, but we do need to stop at some cutoff because it bloats the header up with a pile of of generated code which I guess most people don't need. The limit is always going to be somewhat arbitrary, but my point is that you may just re-run the code generator yourself to set the upper limit to whatever you may need in your own copy of tinyformat.h. It's as simple as pip install cogapp, setting maxParams and running cog -r tinyformat.h.

I'm glad that someone is still getting some value from the C++98 version. I keep considering whether to delete those parts, but I keep them around in the hope that they're useful to someone, somewhere :-)

nigels-com commented 4 years ago

I'm also often in pre-C++11 land. Lots of snprintf.

evandrocoan commented 4 years ago

Yes, please keep them. I will have to work with legacy code for a very long time.

I think the limit could be increased to 32 by default, without much problems. 32 should be a number of parameters very difficult to hit. If you think 32 is too big, 24 could also be a good value.

Your C++ 98 code is not only useful for this library, but for many others which need to support C++ 98 code with variadic templates. For example, I used your exceptional C++ 98 macro tricks in my logging library to create a secure formatting variadic function for C++ 98 code:

#define TINYFORMAT_ERROR(reasonString) throw std::runtime_error(reasonString)
#include <stdexcept>
#include "tinyformat.h"

#define TINYFORMAT_FORMATTER_CREATE_NTH_FORMAT(n) \
template<TINYFORMAT_ARGTYPES(n)> \
inline std::string secure_tinyformat(TINYFORMAT_VARARGS(n)) \
{ \
  try { \
    return tfm::format( TINYFORMAT_PASSARGS(n) ); \
  } \
  catch (std::runtime_error &error) { \
    return std::string( error.what() ) + std::string( ": '" ) + std::string( v1 ) + std::string( "'" ); \
  } \
  catch (...) { \
    return std::string( "Unknown error on the formating string: " ) + std::string( ": '" ) + std::string( v1 ) + std::string( "'" ); \
  } \
}

TINYFORMAT_FOREACH_ARGNUM(TINYFORMAT_FORMATTER_CREATE_NTH_FORMAT)

https://github.com/evandrocoan/cppdebugger/blob/d294e7cd9f6de6129af4f3a8530fb4d6fb763f8a/debugger.hpp#L65-L83

c42f commented 4 years ago

Great, I've always thought this would be nice for loggers (in fact that's largely why TINYFORMAT_FOREACH_ARGNUM exists, and also partly why vformat exists; to support separate compilation of logging backends).

I'll keep the C++98 around for a while longer. It's ugly to look at, but it's been quite stable and easy to maintain. Also I think the backward compat is a meaningful use case for this library vs some other more high profile efforts at fixing C++ formatting relying on more modern features.