Я пытаюсь создать сообщение в буфере фиксированного размера, где пользователь моей библиотеки предоставляет некоторые из данных в нем. Я делал это, предоставляя пользователю указатель на буфер и позволяя им записывать в него и устанавливать аргумент size_t
ссылкой на количество написанных байтов. Я хотел отойти от этого подхода, потому что он позволяет пользователю случайно повредить буфер или неправильно сообщить количество записанных байтов. Для того, чтобы сделать это, я сделал следующее:Является ли этот вариант использования CRTP неопределенным поведением?
Defined этой структуры:
template <class Derived>
struct MsgBase
{
size_t size() const { return sizeof(Derived); }
const char* data() const {
const Derived* dat = static_cast<const Derived*>(this);
return reinterpret_cast<const char*>(dat);
}
};
И я требую, чтобы, если пользователь хочет послать определенные данные, что они определение структуры, унаследованную от этого с данными для отправки. Например:
struct Example : MsgBase<Example>
{
int a;
double b;
char c[7];
};
Я этот класс определен, чтобы помочь им сообщить данные в моей библиотеке:
class Loader
{
public:
Loader() : size(0), data(0) {}
size_t size() const { return size; }
const char* data() const { return data; }
template<class T> void loadData(const T& t) {
size = t.size();
data = t.data();
}
private:
size_t size;
const char* data;
};
И так я их называю так:
{
//pos is a char* to a point in a buffer of data
Loader loader;
onLibraryCall(&loader);
memcpy(pos, loader.data(), loader.size());
}
И пользователь делает это:
void onLibraryCall(Loader* loader)
{
Example e;
e.a = 3;
e.b = 2.7;
e.c[0] = //bla fill out some stuff here
loader->loadData(e);
}
Это работало в бесчисленных двоичных файлах, которые я тестировал с помощью компиляции с использованием разных версий gcc, но последовательно разлагает сообщение в одном конкретном двоичном файле. gdb и valgrind не помогли мне вообще, и проблема исчезнет, если я попытаюсь зарегистрировать то, что происходит прямо над вышеперечисленными вызовами. Это заставляет меня думать, что в этом есть неопределенное поведение, но я не совсем уверен, где это может быть или что я могу сделать для дальнейшего его отладки?
У меня есть проверка, чтобы убедиться, что любые такие определенные структуры являются POD. Я также знаю, что такое все структуры, и в настоящее время они представляют собой комбинацию только интегральных типов и небольших массивов с фиксированным размером.
Это правда! Я попробую это, предоставив загрузчику pointer pos и сразу же выполнив memcpy! –
Это было - поведение исправлено –