“как будто” в стандартах языка

Что является точным значением фразы, "как будто" в стандарте и как, это работает, когда пользователь может изменить отдельные части поведения.

Вопрос в отношении стандарта C++ при разговоре о nothrow версии operator new. Чтения 18.4.1.1/7 (мой акцент):

Эта nothrow версия оператора новые возвраты указатель, полученный, как будто полученный от обычной версии.

Мое понимание - то, что, "как будто" не требует определенной реализации, пока поведение является соответствующим. Итак, если operator new был реализован как это (я знаю, что это не совместимая реализация, поскольку нет никакого цикла или использования new_handler; но я сокращаю это, чтобы сфокусироваться на моей проблеме):

// NOTE - not fully compliant - for illustration purposes only.
void *operator new(std::size_t s)
{
    void *p = malloc(s);
    if (p == 0)
        throw std::bad_alloc();
    return p;
}

Затем было бы законно записать nothrow версию как это:

// NOTE - not fully compliant - for illustration purposes only.
void *operator new(std::size_t s, const std::nothrow_t &nt)
{
    return malloc(s);
}

Но скажем, программа заменяет operator new использовать некоторое другое средство выделения. "Как будто" средний компилятор должен автоматически изменить поведение nothrow версии для использования этого другого средства выделения? Разработчик требуется заменить и плоскость и nothrow версии?

13
задан Kirill Kobelev 23 June 2012 в 02:42
поделиться

3 ответа

Начиная с 1.9 "Выполнение программы:

соответствующие реализации требуются для имитации (только) наблюдаемого поведения абстрактной машины

и в информационном сноска:

Это положение иногда называют правилом «как если бы», потому что реализация может игнорировать любое требование этого международного стандарта до тех пор, пока результат таков, как если бы требование было выполнено, насколько это возможно. определяется из наблюдаемого поведения программы.Например, фактическая реализация не должна оценивать часть выражения, если она может сделать вывод, что его значение не используется и что никаких побочных эффектов, влияющих на наблюдаемое поведение программы, не возникает.

В стандарте особо отмечается, что требование «как если бы» является обязательным для заменяющей версии альтернативной версии оператора new () . Однако, как я читал, это требование выпадет на долю программиста, переопределяющего оператор new () , а не компилятор. Обратной стороной этой ответственности является то, что я думаю, что стандарт в значительной степени требует реализации по умолчанию оператора nothrow new () , предоставляемого библиотекой, который должен делать что-то вроде вызова метода throwing new в try / catch и вернуть 0, если обнаружен std :: bad_alloc .

Здесь могло бы сыграть роль «правило как будто», если бы компилятор / компоновщик / что-то еще было достаточно умен, чтобы выяснить, что, когда использовалось выбрасывание по умолчанию new () , не выбрасывающий по умолчанию new () мог бы использовать ярлык, но если бы выбрасывание по умолчанию new () было отменено, не выбрасывающее по умолчанию new () было бы приходиться действовать по-другому. Я уверен, что это технически возможно для реализации (даже если вы, вероятно, не можете выразить это на стандартном C ++). Я был бы удивлен, если бы когда-нибудь была такая реализация.

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

7
ответ дан 2 December 2019 в 01:31
поделиться

Если изменение аллокатора в operator new вносит заметную разницу в поведение совместимой программы на C++, то да, это может потребовать изменения в реализации версии no-throw. В частности, если оператор delete ожидает только блоки, выделенные новым аллокатором, то no-throw new должен измениться.

Я считаю, что использование as if позволяет реализацию, подобную вашей, когда пользователь не переопределил стандартный оператор new. Как только он это сделал, реализация не должна использовать malloc на основе no-throw operator new и должна либо явно вызывать объявленную пользователем версию, либо, по крайней мере, повторно использовать достаточно объявленной пользователем версии, чтобы соответствующая программа не смогла определить, что это не то, как была реализована no-throw версия.

2
ответ дан 2 December 2019 в 01:31
поделиться

Разработчик должен заменить обе версии - обычную и неброскую. Посмотрите эту статью на GOTW.

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

0
ответ дан 2 December 2019 в 01:31
поделиться
Другие вопросы по тегам:

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