#c #c 17 #language-lawyer
#c #c 17 #язык-юрист
Вопрос:
По правилу cppreference/eval_order 12 вызов функции распределения ( operator new
) выполняется последовательно перед (начиная с C 17) вычислением аргументов конструктора в новом выражении. Таким образом, я подумал следующее
Bar b;
Foo* f = new Foo(b.fun());
во время выполнения new
сначала вызывается, затем fun()
on b
и, наконец, конструктор Foo
. И Clang, и ICC создают этот порядок. Однако fun()
сначала вызывается GCC, затем operator new
конструктор, а затем конструктор.
Кто прав? Чего мне не хватает?
Комментарии:
1. Это gcc.gnu.org/bugzilla/show_bug.cgi?id=86347
2. Учитывая, что новое выражение может создавать
Foo
объект на месте в памяти, выделеннойnew
, это выглядит неоптимальным… Как вы его тестировали, загружали new и печатали?3. @StoryTeller-UnslanderMonica, да, тем временем я тоже нашел. Это сообщение об ошибке более чем 2-летней давности, поэтому его устранение все еще в пути… Даже если это может быть не так важно, но более 2 лет, давайте, ребята! В любом случае, спасибо!
4. @Yakk-AdamNevraumont, да, перегрузить новое.
Ответ №1:
Изучение стандарта (версия N4835.pdf):
7.6.2.7 Новый [expr.new]
23 Вызов функции распределения выполняется последовательно перед вычислениями выражений в новом инициализаторе. Инициализация выделенного объекта выполняется последовательно перед вычислением значения нового выражения.
В вашем случае b.fun()
это единственное выражение в новом инициализаторе.
Похоже, что Clang, ICC и MSVC делают это правильно, а GCC делает это неправильно. Возможно, стоит спросить ребят из GCC и, возможно, отправить отчет об ошибке (или, может быть, он уже существует?).
Комментарии:
1. Это не обязательно, но было бы неплохо добавить ссылку на черновик, на который вы ссылаетесь.