4 ms·
> 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 t
by 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.
- dataflow 3y agoYeah I wouldn't call that working on MSVC either haha.
- gavinsyancey 3y agoDefinitely not "working", yeah, but On MSVC, an all-zero string object is the correct representation for a std::string containing "" (and the memory leak is easy to miss if you don't do it too much). On both Clang and gcc, an all-zero string object is not using the short-string optimization -- it is a string with size zero, capacity zero, and an external buffer of nullptr. (On clang this happens because capacity is even, and on gcc because &str->buf != &str). Any code that attempts to access its null terminator will dereference the null pointer and crash immediately.
- dataflow 3y agoYeah I get that.
- maccard 3y agoIf your string hadn't allocated yet then nope, probably not.
- rewmie 3y ago> They had discovered that you could clear a string under MSVC by `memset()`ing over it. Why was that? Was it too problematic to just call std::string::clear ?
- filmor 3y agoSSO is "small string optimization", in case anyone was wondering.