That said, here's an example:
// imagine this with string_view
FILE* openFileInPath(const std::string& path) {
if (path.starts_with("some_dir"))
{
return fopen(path.c_str());
}
return nullptr;
}
That function works just fine to only open a path that has a prefix (logic bug on relative paths aside for brevity while posting)I should be able to pass a constexpr string to that function the same way I can pass a runtime created string.
I think of constexpr functions as something which occur at compile time, and I thought this linked-to piece was about what can take place inside those functions.
As I understand it, you want to create a constexpr string so it can be passed to a char*. The issue is this requires heap allocation (for large enough strings, based on the compiler implementation).
The C programmer in me wonders why you don't "char[]" allocate the static memory buffer, then pass around a string view, so the constexpr doesn't need heap at all.
There's a few reasons. Avoiding the heap allocation is one, yep. There just shouldn't be a difference between a compile time string and a runtime string. As a programmer I don't want to have to deal with "which flavor of string am I dealing with".
The issue with passing to a c API (I used fopen, but think of any c library - zlib/gzip, openssl, sqlite) is that the string needs to be null terminated, and string view doesn't guarantee null termination.
int foo(std::string_view view) {
return strlen(view.data());
}
std::string str("hello world");
foo(str):
std::string_view view = str;
foo(view);
view.remove_suffix(6); // now view is just "hello" with no null termination
foo(view); // this is wrong.
The problem isn't _specifically_ constexpr std::string in this case, it's that the tools that you use to generalise working with runtime strings, char buffers, and views aren't fit for purpose.In the 1990s there was only one string type - NUL-terminated characters. ;)
I keep reading about all the neat algorithms (and multi-threading) support in modern C++, but the complexity of the decades of history and the difference in mindset between {C, Python} and C++ have made me shy away.
I think I'll keep mum from a distance in future discussions until I decided to (re) take up the language seriously.
Indeed. If I could wave a magic wand, I would add a fat pointer to the language that we use to represent strings and arrays, and that we can automatically convert to/from const char* at compile time. This would replace string_view and span. All of the functionality of std::string would be available to it, and a call to strlen, or strcpy on it would work via the length, rather than the null terminator.
But alas, no magic wand.
Then again, I am primarily a Python and C programmer, so there is likely some underlying reasoning I'm missing.
in C++ cannot change after construction, but is not compile time constant. This means that it has to run some code and allocate some memory at runtime.
In contrast constexpr is fully compile time and ends up in the read only portion of the binary. No code code execution or allocations necessary.