fenbf / cppstories-discussions

4 stars 1 forks source link

2022/sso-cpp20-checks/ #104

Open utterances-bot opened 1 year ago

utterances-bot commented 1 year ago

How to Measure String SSO Length with constinit and constexpr - C++ Stories

What is SSO   Just briefly, SSO stands for Short String Optimization. It’s usually implemented as a small buffer (an array or something similar) occurring in the same storage as the string object. When the string is short, this buffer is used instead of a separate dynamic memory allocation.

https://www.cppstories.com/2022/sso-cpp20-checks/

2kaud commented 1 year ago

Note that both std::string_view and std::array can be constexpr with no size limitations (other than available memory!). So if you need a constexpr string, use std::string_view instead of std::string (or even for just a const string).

fenbf commented 1 year ago

See comments at reddit/cpp: https://www.reddit.com/r/cpp/comments/z0v08g/how_to_measure_string_sso_length_with_constinit/

fenbf commented 1 year ago

ah yes @2kaud , good point about string_view they are not limited to SSO buffer length...

2kaud commented 1 year ago

Re reddit. .capacity() became constexpr in C++20. So for C++11, 14, 17 you can only specify const.

#include <iostream>

const auto sso_size { std::string{}.capacity() };

int main() {
    std::cout << sso_size << '\n';
}

which for VS displays

15
2kaud commented 1 year ago

Re constinit "In short, our object will be initialized at compile time"

Hmmm.... Consider

#include <string>

constinit std::string s { "qwerty" };

int main() {
    static_assert(s.size() == 6);
}

where the static_assert fails with the error "expression did not evaluate to a constant"

fenbf commented 1 year ago

good point @2kaud ! constinit forces constant initialization of a variable, but this doesn't mean the variable can ba later used in constant expressions. In fact you get a "normal" static variable that can be changed later.

uzoochogu commented 1 year ago

Amazing article! An update:

constexpr std::string str15 {"123456789012345"};

int main() {
    std::cout << str15 << '\n';
}

This now works in Clang 17.0.1

Mr-Auto commented 7 months ago

The Clang implementation (-stdlib=libc++) can store 23 characters! It’s very impressive, as the size of the whole string is only 24 bytes!

It's 22, not 23, since there is one character for null termination and one to hold the size. Unless the point was to count the null character, but then the GCC and MSVC should be 16 https://godbolt.org/z/696ddKnY3