Код: Выделить всё
#include
#include
#include
#include
#include
#include
struct String {
std::size_t size;
std::size_t capacity;
char *buf;
template
String(const char (&s)[N]) : size(N - 1), capacity(N), buf(new char[N])
{
memcpy(buf, s, N - 1);
}
String(const String &) = delete;
~String() { delete[] buf; }
const char *c_str() const
{
assert(size < capacity);
if (buf[size] != '\0') [[unlikely]] // UB
buf[size] = '\0';
return buf;
}
};
String greeting("hello world");
int
main()
{
greeting.c_str(); // NUL-terminate string before spawning threads
std::vector greeters;
for (int i = 0; i < 24; ++i)
greeters.emplace_back([] { std::puts(greeting.c_str()); });
}
Первый вопрос для юристов языка: правильно ли я понимаю, что код - UB, и есть ли способ получить то, что я хочу внутри язык?
Если строгий C++ безнадежен, мой код должен работать только с gcc и clang, поэтому мой второй вопрос: могу ли я каким-то образом отмыть указатель через встроенную функцию компилятора. Он должен работать на нескольких архитектурах, но я готов отмывать байт с помощью пустой директивы asm, которая подразумевает помещение значения в байт, хотя на самом деле не содержит никакого кода. Например, будет ли следующее безопасно и работать на большинстве архитектур?
Код: Выделить всё
const char *c_str() const
{
assert(size < capacity);
asm("" : "=m" (buf[size]));
if (buf[size] != '\0') [[unlikely]] // no longer UB?
buf[size] = '\0';
return buf;
}
Подробнее здесь: https://stackoverflow.com/questions/798 ... alues-in-c
Мобильная версия