Какой самый быстрый способ узнать, где создаются временные файлы в моем коде C ++?
Ответ не всегда легко выводится из стандарта, и оптимизация компилятора может дополнительно устранить временные потери.
Я экспериментировал с godbolt.org и это фантастика. К сожалению, это часто скрывает деревья за древесиной ассемблера, когда речь идет о временных. Кроме того, агрессивные опции оптимизации компилятора делают ассемблер полностью нечитаемым.
Есть ли другие способы сделать это?
«Оптимизация компилятора может дополнительно устранить временные потери».
Кажется, у вас есть небольшое неправильное понимание семантики C ++. Стандарт C ++ говорит о временных временах для определения формальной семантики программы. Это компактный способ описания большого набора возможных исполнений.
Настоящий компилятор не должен вести себя так. И часто они не будут. Реальные компиляторы знают о регистрах, настоящие компиляторы не делают вид, что POD имеют (тривиальные) конструкторы и деструкторы. Это происходит уже до оптимизации. Я не знаю ни одного компилятора, который будет генерировать тривиальные ctors в режиме отладки.
Теперь некоторая семантика, описанная в Стандарте, может быть достигнута только в достаточно близком приближении. Когда деструкторы имеют видимые побочные эффекты (подумайте std::cout
), временные типы этих типов не могут быть полностью устранены. Но настоящие компиляторы могут реализовать видимый побочный эффект, не выделяя никакого хранилища. Понятие временного существования или несуществования является бинарным представлением, и в действительности существуют промежуточные формы.
Из-за правила «как если бы», вероятно, ненадежно пытаться просмотреть процесс компиляции, чтобы увидеть, где создаются временные файлы.
Но чтение кода (и кодирование) с учетом следующего параграфа стандарта может помочь определить, где создаются временные фильтры, [Class.temporary] / 2
Материализация временного объекта обычно задерживается как можно дольше, чтобы избежать создания ненужных временных объектов. [Примечание: временные объекты материализуются:
при привязке ссылки к prvalue ([dcl.init.ref], [expr.type.conv], [expr.dynamic.cast], [expr.static.cast], [expr.const.cast], [expr] .бросать]),
при выполнении доступа члена к классу prvalue ([expr.ref], [expr.mptr.oper]),
при выполнении преобразования массива в указатель или подписки на значение массива,
при инициализации объекта типа std :: initializer_list из списка braced-init-list ([dcl.init.list]),
для некоторых неоцененных операндов ([expr.typeid], [expr.sizeof]) и
когда значение prvalue появляется как выражение отброшенного значения.
В этом абзаце, исходя из стандарта C ++ 17, термин prvalue имеет новое определение [Basic.lval] / 1:
Значение prvalue — это выражение, оценка которого инициализирует объект или битовое поле или вычисляет значение операнда оператора, как определено контекстом, в котором оно появляется.
И в последнем стандарте (до C ++ 20) абзац [basic.lval] был перемещен в Выражения [expr], так что то, что мы знали как ценностные категории, развивается, чтобы стать категориями выражений.