9 ms·
Just how constexpr is C++20’s std:string?
- eclectic29 3y ago[deleted]
- vore 3y agoThis is extremely off topic — what does any of this have to do with constexpr strings?
- jfoutz 3y agoEr, I'm way out of touch with modern c++, what implementation do you buy? Borland used to have tons of little helpers and utils to smooth over some rough edges. I'd imagine ms vc++ has tons of stuff to support this? Again, I haven't used a commercial compiler in a while. But that seems like really standard stuff you get with them, yeah?
- frozenport 3y ago3rd party libraries provide that functionality, and do it with higher performance than in any other another language
- deleted 3y ago[deleted]
- frozenport 3y agoeasy fix: just make a std::constexpr_string
- lionkor 3y agoit has to be something ridiculous like std::basic_string<char, ..., std::argh::boink::constexpr_trait{}()<!?>>
- nuancebydefault 3y agoReading this is really making me sigh. What is C++? A language used to make applications or a language for the sake of the language? It often feels like math professors discussing math for the fun of it, not for solving practical problems.
- deleted 3y ago[deleted]
- andersa 3y agoLuckily, one can just ignore all the modern C++ shenanigans and use it as not much more than C with classes and some basic templates for generic containers. Those are too useful to give up.
- jcul 3y agoYou can, but the modern stuff (in the last decade or so) have made it so much nicer and more fun to work with.
- gemstones 3y agoIs everyone on a team of one in C++ land? I kind of want to learn a bit of C++ but to be honest, I’m a bit scared off by the fact that it’s only workable if you stick to a specific style. If I learn C++, will I be completely lost the moment I change teams? Presumably they’ll have their own set of practices they like to follow that I’ll be expected to be productive with.
- hedora 3y agoYou want to be on a team that contains a C++ expert or two, and they should conscientiously and continuously evolve your code base to incorporate more static time correctness checks and to be more in line with where the standard library is heading.
- andersa 3y agoMost large teams totally ignore whatever the standard library is doing, because it's largely just bad, over engineered and slow, both to compile and at runtime. They then have their own developed from scratch. It would be funny if it wasn't so sad. For example, even though both Chromium and Unreal Engine are using C++, good luck finding basically anything high level in common. All of the naming schemes are different, the formatting is different, the high level libraries are unrecognizable. It almost feels like these projects are written in different languages. Beneath all of that, they do make use of the same low level mechanics. A pointer is still a pointer, no matter what libraries you build on it. A stack allocation is still a stack allocation, passing something by a const reference is still the same, passing universal references to container templates is still the same. Includes work the same everywhere. And so on. Basically, unlike most other languages, you want to have a solid understanding of these underlying mechanics so you can then quickly understand whatever high level libraries the project decided to build on top and hit the ground running using those. There's gonna be some kind of resizable array thing in every project. But yes, you're basically starting over re-familiarizing yourself with the language on every large project or framework you explore. I've been using C++ for many years and never once used a std::string, since each framework has its own clearly superior string...
- seeknotfind 3y agoIt's really unfortunate the heap allocation can't be in .ro.data for constexpr std::string. It might be an invasive change, but it would beat the hell out of const char* there for the reason of avoiding a copy onto the heap.
- dheera 3y agoI hate const char*. This notation sucks. Is it (const char)* or const (char*)? i.e. is it a pointer to a char but the memory address it points to is const, or is it a variable pointer that points to a const char.
- 10000truths 3y agoIt is the former, a pointer to a const char. A const pointer to char would be qualified as: char* const
- Koshkin 3y agoconst char* const f() const is the best!
- ndesaulniers 3y agoI think const char * and char * const are obvious (whichever the const keyword is closest to). That rule of thumb doesn't work though for char const * or char * const * though.
- dheera 3y ago> char * const Oof no I HATE this. I also hate it when people write char *a; because the type is char* (i.e. pointer to a char) and the name of the variable is a.
- moregrist 3y ago`char * const a` is a different type from `const char *a`. In the first, the variable `a` is const, but `*a` is not const. That is, you cannot change the value of `a` but you can change what it points to. In the second `a` is not const, but `*a` is. That is, you can change `a` but you cannot change the value it points to. I feel that your confusion is tied up in not understanding how C and C++ type declarations work, as is your insistence on `char* a`. Dennis Ritchie (the C language designer) intended it to be written as `char *a` and talked about this at length over the years as an important design decision: variable declaration follows _usage_, so it’s `char *a` because the type of `*a` is `char`. For better or worse, Stroustrup took this design decision into C++. Sure both will parse in this simple case, but keeping this in mind is also the way that more complex declarations make sense.
- ljosifov 3y agoFor many years the best language(s) experts have been trying to have compile time and run time strings live together happily ever. They come tantalizingly close but don't quite succeeded. Maybe it is time to entertain the idea that even if compile and run time strings look so similar as to be almost the same - maybe they are not? Maybe they are actually more dissimilar than they appear? Compile time strings to me look more like symbols table: strings unique and ideally sorted. The offset can be a handle - then uniqueness means we can == or != compare handles rather than strings. If the table is sorted, then < > <= >= compares of symbols via their offsets just works too.
- cmovq 3y ago> libstdc++ rejects the following code (Godbolt [1]). (Microsoft accepts, but I think that might be an MSVC bug.) This is not a bug in MSVC, rather it is due to MSVC implementing std::string SSO differently than gcc or clang. Instead of initializing `data` as pointing to the internal buffer for small strings, MSVC uses the string's capacity to determine whether to access `data` or the internal storage [2]. Hence this code compiles, as it's not initializing the string using a stack address. [3] [1]: https://godbolt.org/z/1ErrKjdbq https://godbolt.org/z/1ErrKjdbq [2]: https://devblogs.microsoft.com/oldnewthing/20230803-00/?p=108532 https://devblogs.microsoft.com/oldnewthing/20230803-00/?p=10... [3]: https://godbolt.org/z/1MaxdGfvj https://godbolt.org/z/1MaxdGfvj
- rileymat2 3y agoThat's fine that it is not a bug, but it seems like a compatibility nightmare.
- fake-name 3y agoIt can lead to "fun" optimizations. I spent a while porting a codebase that was written by someone far more clever then smart. They had discovered that you could clear a string under MSVC by `memset()`ing over it. Obviously, this exploded in linux. That was a fun bug to track down.
- dataflow 3y agoHow does that even work on MSVC? Wouldn't it leak memory?
- gavinsyancey 3y ago> How does that even work on MSVC? It sets the capacity to zero. MSVC then interprets it as a short string with length 0, which doesn't have an external allocation. > Wouldn't it leak memory? Yes, but I assume the "far more clever then smart" programmer didn't notice.
- deleted 3y ago[deleted]
- zX41ZdbW 3y agoconstexpr is often difficult to get right. For example, we use a wide_integer type for 128 and 256-bit integers: https://github.com/ClickHouse/ClickHouse/blob/master/base/base/wide_integer_impl.h https://github.com/ClickHouse/ClickHouse/blob/master/base/ba... It was developed by a C++ expert to fit into the C++ standard, so it has constexpr everywhere. But for this reason, we cannot use memcpy inside its methods and have to wait for a new standard with constexpr memcpy. Note: memcpy is to satisfy strict aliasing - we can use std::bit_cast instead, but there was some trouble.
- gpderetta 3y agoI'm still on C++20, so I haven't had a chance to try it yet, bit 'if consteval' should allow fixing this, right?
- zX41ZdbW 3y agoThank you! Should work. PS. When reading about `consteval`, `constinit` you might think, "they (C++ committee) are totally crazy, how they think we can follow"
- Koshkin 3y ago> : Meant to be ‘::’, of course. (This abomination can only compete with the ML’s double semicolon.)
- 1024core 3y agoMy C++ knowledge is from the old days. What book would one recommend to learn _and understand_ these new fangled concepts like "constexpr", "constinit", std::move, std::unique_ptr, closures, etc.
- pjmlp 3y agoTour of C++, written by Bjarne Stroustrouop, exactly for those with prior knowledge .
- beyondCritics 3y ago> In real life, there’s basically no reason ever to use constexpr on a stack variable Wait what? This is what i was doing right now. It defines a local compile time constant and hence is an important mean to express an abstract concept. You could use a macro, but we are told to get rid of them. And a local const variable is an entirely different thing.
- twic 3y agoI think the idea is that things like that should be static constexpr. They have the same lexical scope but don't take up space on the stack. Surely any competent optimiser will make them the same though.
- elteto 3y ago> In real life, there’s basically no reason ever to use constexpr on a stack variable; you’ll use it only on globals or as part of the set phrase static constexpr. Hmm… this is just unnecessarily dogmatic. I use constexpr all the time, for example, for local numerical constants that don’t need to be a global.
- Thorrez 3y agoWhy not use a static local constexpr? That seems like it would be faster to me due to not needing to allocate stack space and copy the value to the stack. You still get the benefit of not needing a global.
- elteto 3y agoIf the variable is numeric, and const or constexpr, and you have -O1 or higher enabled, then the compiler will optimize it away. I don’t think static would add anything under these conditions.
- Aardwolf 3y agoIs accepting 11-char strings but not accepting 19-char strings for constexpr, specified in the C++ specification, or is this just behavior that different compiler vendors are implementing differently? If the latter, then it is pretty annoying that non-standard behavior is happening now related to standard libraries implementations and constexpr.
- juliangmp 3y agoThis is just genuienly awful for the user. Put yourself back to the times when you first started to learn C++, maybe programming in general. And now you have to wonder why one of your string constants is just fine and the other one gives you some weird error in allocator.h or something...
- kccqzy 3y agoI find that there's no use case for a constexpr std::string. Maybe I'm just not imaginative enough. If I want a string literal constant, I use string_view which can be constexpr. If somehow I need an actual std::string object, I use a regular const not constexpr. What would be a use case that prompts the author to explore using constexpr with std::string?
- hudsonwillis 3y agoIt enables users to process string at compile time. You can implement a constexpr getRFC3339DateString(int year, int month, int day) -> string and then construct a constexpr string list.
- kccqzy 3y agoBut what can you do with that string list afterwards? You can't store it anywhere to be accessed at run time, can you?
- Chabsff 3y agoThe important part is that all the intermediate strings used during the computation are constexpr, to guarantee that the work happens during compilation. Also, constexpr symbols can be demoted to regular const as needed by the compiler if necessary, such as when getting a pointer to one. constexpr doesn't mean "compile-time only", it means "compile-time compatible"
- lldb 3y agoRight - you can use the std::string at compile time but since it allocates dynamically you need to copy to a fixed size char[]/std::array to use at runtime.
- maccard 3y ago> If I want a string literal constant, I use string_view which can be constexp That assumes your API accepts string views. How do you pass a string_view (safely) to fopen, or CreateFile (on windows)?
- alphanullmeric 3y agoMuch more than rust, that’s for sure, where you are forced to stick everything in a macro or pray the compiler is smart for compile time programming.
- insanitybit 3y agoNot to derail, because frankly I think it's very weird to even bring Rust up here, but `const fn` is a thing in Rust and is guaranteed to execute at compile time. It is more limited, no question. But you don't have to hope that the compiler will do things, it is guaranteed to do them.
- alphanullmeric 3y agoIt’s not any weirder than promoting rust under discussions about c++, unless you think any mention of rust must be positive. There is pretty much nothing useful, this post included, that can be done with const fn in rust.
- insanitybit 3y ago> It’s not any weirder than promoting rust under discussions about c++ Feels like a straw man? I never promoted Rust, certainly I didn't bring it up unprompted. I corrected someone who brought it up. > unless you think any mention of rust must be positive. Again, feels like a straw man. I said nothing of the sort. > There is pretty much nothing useful, this post included, that can be done with const fn in rust. I feel like you're simultaneously upset that I corrected your post... but also you're challenging my point, in an attempt to pursue discussion? It's confusing because you're wrong but there's also an interesting discussion to be had - although I think this post covers the general issue of "what is a pointer at compile time" quite well.
- alphanullmeric 3y agoI didn’t accuse you of doing it, I said you only find other people bringing up rust weird if it’s not positive. Unless you want to agree that it’s always weird to bring up rust in a discussion about c++? I’m not upset about anything. You said I’m wrong, so show me how you use const fn to make a heap allocated string at compile time as done in this post.