C ++ «заменит» структуру с гибким членом массива

Рассмотрим следующую структуру C99, заканчивающуюся элементом гибкого массива:

struct hdr
{
size_t len;
size_t free;
char buf[];
};

lenнапример, доступ к нему осуществляется с помощью встроенной функции (для помещения в файл заголовка), например buf в качестве аргумента:

static inline size_t slen(const char *s)
{
struct hdr *h = (struct hdr*)(s - (int)offsetof(struct hdr, buf));
return h->len;
}

Это часть библиотеки, которая должна быть скомпилирована с помощью компилятора Си. Тем не менее, я хотел бы получить доступ к этой библиотеке из C ++; это по существу означает, что соответствующий заголовочный файл (с надлежащим extern "C" {...} guard) должен быть действующим кодом C ++. Возможным решением является определение slen функция в теле исходного кода, полностью избегая встроенного кода, но это не оптимально.

Моя идея состоит в том, чтобы определить фиктивную структуру C ++, которая является действительной, и которую я могу как-то сопоставить hdrнапример,

struct cpp_hdr
{
size_t len;
size_t free;
char buf[1];
}

Обратите внимание, что я хочу получить только правильные (отрицательные) значения смещения для len а также free; нет доступа к buf предназначен.

Теперь мой вопрос: есть ли гарантия того, что

static inline size_t slen(const char *s)
{
struct cpp_hdr *h = (struct cpp_hdr*)(s - (int)offsetof(struct cpp_hdr, buf));
return h->len;
}

работает, дает тот же результат?

4

Решение

В формальном ничего не гарантировано, потому что C ++ не поддерживает гибкие массивы: такого понятия нет, такого синтаксиса нет.

На практике компиляторы не делают ничего без прямой причины. Так что не будет введено ни одного волнистого дополнения. Однако, чтобы сделать это совершенно ясным, я бы использовал размер массива, например 666 вместо 1, что лучше работает в более общем случае (например, небольшой массив 1 char может быть перемещен в другую область заполнения в какой-либо другой структуре). В качестве преимущества умный код для размещения больше не будет выглядеть просто. Так что это должно быть сделано правильно.

Все это говорит, это звучит как 16-битная Windows BSTRкроме BSTR нет такого разрыва между длиной и строковыми данными. Подумайте, не является ли эта библиотека просто чьим-то безосновательным переизобретением колеса. Если это так, я предлагаю использовать оригинальное колесо вместо.

1

Другие решения

Предполагая, что библиотека была скомпилирована другим компилятором, не гарантируется, что смещение будет таким же. Практически, это должно работать большую часть времени.

Если вы работаете с конкретным компилятором, вы можете использовать отладчик и настроить вычисление смещения для этого компилятора и сделать утверждение в начале, чтобы убедиться, что ваше предположение (настройка) остается верным, если позже вы решите перейти на другой компилятор или более новую версию. ,

1

По вопросам рекламы [email protected]