5 ms·
What's wrong with std::regex? Seems to work fine for me. And iostreams - they're not great. Bad programming UI, poor performance, etc. Issues abound. But shoul
by verall 3y ago
What's wrong with std::regex? Seems to work fine for me.
And iostreams - they're not great. Bad programming UI, poor performance, etc. Issues abound. But should you never use them? What do you use instead? *printf methods have lots of issues too. And so does depending on Boost::format. And so does writing your own Logger/wrapping code (which is what everyone does AFAICT).
locale is bad though
- gpderetta 3y agoiostreams are not great but are nothing compared to the awkwardness and lack of extensibility of printf style format strings.
- einpoklum 3y ago1. Historically, std::regex was offered in GCC before it was actually fully implemented. Much hilarity ensued... 2. Some existing implementations have efficiency issues, e.g. performing many allocations. 3. It is claimed (e.g. by Titus Winters) that the ABI of std::regex is problematic, and without breaking it, the implementations cannot be good enough See these points and others at: https://www.reddit.com/r/cpp/comments/e16s1m/what_is_wrong_with_stdregex/ https://www.reddit.com/r/cpp/comments/e16s1m/what_is_wrong_w...
- npsimons 3y ago> What do you use instead [of std::iostream]? This is what I want to know. Having come from C to C++, iostreams were a big improvement over the "strings" and print functions of C. I even extended a base iostream class to have a "teebuf" logger, that could output to multiple streams and had the standard logging levels. It's been a while since I last had mastery of C++, but I'd like to hear what is as portable and better than iostreams.
- usefulcat 3y ago> I'd like to hear what is as portable and better than iostreams Have a look at fmtlib. The interface is more like printf, but type safe and format strings are parsed at compile time. I believe it’s what std::format is based on, which could also be an option for you depending on how recent your compiler/language version is.
- npsimons 3y ago> The interface is more like printf See, I don't believe that's an improvement. Having used printf in C, I was relieved to be able to "redirect" whatever to a stream, and not care about whether it should be "%d" or "%02f" or even if it was a struct/class. On top of this, treating files as streams, strings as streams, or even extending streams to make a tee-stream[0] all seem clunkier to me with a printf like system. Maybe fmt fixes these problems, I don't know. But I feel a lot of people don't like iostreams because they have some form of Stockholm syndrome with printf. [0] - https://wordaligned.org/articles/cpp-streambufs#tee-streams https://wordaligned.org/articles/cpp-streambufs#tee-streams
- dietrichepp 3y ago> Maybe fmt fixes these problems, I don't know. Yeah, it looks like you did a lot of guesswork in that comment, and a lot of those guesses were inaccurate. Not really trying to be hostile here, but you did acknowledge that you were unfamiliar with std::format. The part that fmtlib / std::format has, which is printf-like, is the idea of having a format string and arguments, rather than having a bunch of separate, piecemeal strings. // Old printf code, works ok for most people std::printf("failed to clone %s from %s", target, src); // <iostream> std::cout << "failed to clone " << target << " from " << src; // New std::format / fmtlib std::print("failed to clone {} from {}", target, src); You can see that you don't need to remember what kind of format specifier you need. This is C++, and that kind of problem is solved with overloading. The std::print interface can work equally well with FILE or std::ofstream, or whatever you want. This is C++, and so you can just use a templated output iterator—or one of the overloads that creates one automatically. There are a lot of problems with <iostream>. I think it’s telling that lots of languages have copied printf, but nobody (or almost nobody) thought <iostream> was good enough to copy. There are just too many serious design flaws with <iostream>. It would be one thing if <iostream> were just annoying to use, but it poses problems for localization, thread-safety, accidental misuse through its statefulness, and its operator overloading syntax is bad.
- tialaramex 3y ago
- dietrichepp 3y agoStrings in C++ are nice, especially now that we have std::string_view, but <iostream> is one of the worst pieces of the C++ standard library. - <iostream> makes localization more difficult, compared to printf (localizing <iostream> code is beyond awful) - <iostream> makes thread safety more difficult, compared to printf (it is safe to printf/fprintf from multiple threads, simultaneously, without any extra work) - The <iostream> operator overloading syntax is bad (my sense is that the operator overloading abuse in <iostream> was a contributing factor for why Java doesn't allow operator overloading) - Streams in <iostream> are stateful, and it's easy to accidentally leave them in the wrong state (radix, padding, field width, etc) - Performance of <iostream>, out of the box, is mediocre (to get decent performance, you need to change some defaults) The main advantage of <iostream> was that it provided type safety, but IMO that advantage has long since been irrelevant. You get type safety with std::printf, with most compilers, assuming you enable -Wformat on GCC or similar options in other compilers. The only remaining advantage of <iostream> is that you can overload operator<<. I don't think that's much of an advantage, especially weighed against the numerous disadvantages. Using std::printf is better and more portable. Libfmt is also better and more portable, and it is now part of the standard library as std::format. https://www.moria.us/articles/iostream-is-hopelessly-broken/ https://www.moria.us/articles/iostream-is-hopelessly-broken/
- therein 3y agolibfmt is definitely recommended. About 6-7 years ago back when my employer was running code compiled with gcc-4.4.7 and running it on Linux 2.6.32 boxes even though it was pretty old even back then, it took me a lot of convincing the company to give libfmt a try. It was such a boost to developer happiness. People were literally overjoyed, writing to me on Slack how much of a pleasure string formatting has become.
- offices 3y ago>The <iostream> operator overloading syntax is bad In an obnoxious way. The first code someone will see of a new language is often 'hello world'. In C++, 'hello world' is an advertisement for the fact that operator overloading exists.
- scatters 3y agoiostream is replaced by format.
- plq 3y ago> What's wrong with std::regex? In my experience, stdlibc++ <regex> is VERY slow, especially on debug builds. We are using g_regex instead, which in turn uses pcre2. > And iostreams <iostream> achieves too little with too much code. We instead use: std::cout << fmt::format(...); for simple output, loguru[1] for everything else. I feel like the fmt grammar/mini-language is both nicely extensible and has hit the expressiveness sweet spot -- not too verbose (iostreams) nor too terse (printf). I also like that fmt has helpers for pointers (fmt::ptr), enums (fmt::underlying) and arrays (fmt::join). It's both easy on the eyes and feels consistent. [1]: https://github.com/emilk/loguru https://github.com/emilk/loguru
- _eojb 3y agoWell, `std::regex` is literally orders of magnitude slower than other common regex libraries found in JS, Python, Perl, C, etc. It allocates a ton, is poorly implemented, and can never be fixed due to ABI constraints. The entire <regex> subsystem is a mess and should have never been standardized as is.
- johannes1234321 3y agoWhile that is true it can still be a good thing to use on a non-perofrmance critical path instead of adding a dependency on an external library. Maybe it shouldn't be there and some better thing should be there, but given it exists ... as long as one is aware of alternatives using it is fine.
- TylerGlaiel 3y agothe last time I tried it (it was years ago) std::regex was taking a measurable number of milliseconds to evaluate which is kind of a very long time even outside of performance critical paths.
- ninepoints 3y agoThere's "not fast but usable enough" of course, but I would never ship std::regex code on any user facing software. Forget realtime, std::regex fails to be interactive in examples where other libraries resolve quickly.
- otabdeveloper4 3y agoThere's nothing wrong with the std::regex design as it is the standard. std::regex only sucks because the developers of gcc and clang never bothered to optimize it. (Too much work and they have other stuff to worry about.)
- leni536 3y agostd::regex also depends on locale, which is reason enough to avoid it, regardless of performance.
- trws 3y agoIt’s impossible to implement std::regex efficiently due to internal but exposed character handling requirements. To the sibling comments about iostream, thank vzeverovich and everyone that worked on fmt and turning it into std::format (edit: accidentally wrote std::fmt initially), which is vastly superior and not dependent on mutable global state.
- tcbawo 3y agoIMHO, the printf-style API is superior to the stream based API, because it can be adapted into a logging API that defers string formatting or delegates it to another thread. Overloading by type can be accomplished with printf-style API as well. Cluttering business code with string formatting can be a liability in code that needs to be performant/low latency, which is one of the primary reasons people use C++.