Гарантия и имя C ++ для данных, подобных POD, с поддержкой memcpy

 DateTime.Today.ToString("MM/dd/yy")

Взгляд на документы для пользовательские строки формата даты и времени для большего количества информации

(О, и я надеюсь, это приложение не предназначено для других культур. Тот формат мог действительно смутить много людей... Я никогда не понимал целую вещь месяца/дня/года, чтобы быть честным. Просто кажется странным пойти "среднее/низкое/высокое" с точки зрения масштаба как этот.)

17
задан Community 23 May 2017 в 11:53
поделиться

1 ответ

Одна из проблем вашего примера в том, что он имеет неявно объявленный, тривиальный деструктор. Несмотря на название, реализация AFAIK не запрещает делать что-то в тривиальном деструкторе класса, не являющегося POD.

Таким образом, юридически в какой-то странной реализации ваш класс ex_struct может демонстрировать поведение во время выполнения, эквивалентное следующему:

struct weird_ex_struct
{
  int a,b,c,d;
  weird_ex_struct() : a(123), aptr(&a) { }
  weird_ex_struct(const weird_ex_struct &o) : 
    a(o.a), b(o.b), c(o.c), d(o.d), aptr(&a) {}
  weird_ex_struct &operator=(const weird_ex_struct &o) {
    a = o.a; //etc
    aptr = &a;
    return *this;
  }
  ~weird_ex_struct() {
    if (aptr != &a) std::terminate();
  }
private:
  int *aptr;
}

Я говорю поведение во время выполнения, потому что weird_ex_struct имеет нетривиальный деструктор, и это влияет на то, как оно может быть легально использовано (с одной стороны, не в союзах). Кроме того, я думаю, что есть стандартные способы обнаружения существования закрытых элементов данных во время компиляции. Но до тех пор, пока реализация может хранить эту информацию в секрете, если вы не сделаете что-то неопределенное (memcpy объект не POD), это позволит вам потом преподнести сюрприз.

Очевидно, что если weird_ex_struct скопировать с memcpy, то что-то странное произойдет, когда он будет уничтожен.

Нет очевидной причины для реализации, чтобы сделать это, но стандарт оставил не-POD классы широко открытыми для реализаций, чтобы делать странные вещи. Не уверен, что это потому, что они думали, что кто-то подумает о какой-то полезной странности, или просто потому, что не удосужились определить стандартную структуру , как это делает C ++ 0x.

[Редактировать: Йоханнес указал, что я ошибаюсь в отношении тривиальных деструкторов - по причинам, изложенным в части стандарта, касающейся времени жизни объекта, реализация не может делать вещи в тривиальных деструкторах, которые полагаются на содержимое память об объекте. Возможно, они могут, если деструктор вызывается явно, я не уверен.

Однако факт остается фактом: стандарт позволяет реализациям совершать довольно много безумных вещей с объектами, не относящимися к POD, и как только вы пишете конструктор, вы открываете эту дверь.]

1
ответ дан 30 November 2019 в 14:28
поделиться
Другие вопросы по тегам:

Похожие вопросы: