То есть она принимает forwarding reference, что позволяет передавать ей в качестве аргументов временные объекты. В моем случае - результат вызова fmt::arg. Это значит, что результат вызова make_format_arg можно сохранить и позже использовать, но только в том случае, если аргумент fmt::arg - l-value reference.
Но в остальном вы правы. Здесь несколько иная проблема, чем то, что описано в статье. Я поправлю. Спасибо
Зачастую разного рода ошибки попадают в продакшн код, проходя ревью действительно опытных разработчиков. Наличие самого процесса код ревью, как и наличие тестов в коде, не гарантирует отсутствие ошибок в нем
Насколько я помню, такой подход был выбран из-за возможности избежать лишнего перемещения, когда сконструированный по-умолчанию объект класса std::thread заменяется только что созданным в теле конструктора. Но, конечно, вы правы, тут только такой подход позволил бы избежать UB
C++ все это позволяет в отличие от, например, Rust. Если вы писали промышленный код на C++, то согласитесь со мной, что внимательное чтение учебников и документации все равно не спасает от подобных багов
Понимаю, что проблема синхронизации потоков имеет место во многих языках. C/C++ интересны тем, что их стандарты вводят определение Undefined Behavior. То есть стандарт прямо говорит, что в этой ситуации может произойти что угодно. В моем случае метод поиска в таблице не работал. Это выглядело интересно
У меня на работе fmt версии 9. Там функция
make_format_args
выглядит так:То есть она принимает
forwarding reference
, что позволяет передавать ей в качестве аргументов временные объекты. В моем случае - результат вызоваfmt::arg
. Это значит, что результат вызоваmake_format_arg
можно сохранить и позже использовать, но только в том случае, если аргументfmt::arg - l-value
reference.Но в остальном вы правы. Здесь несколько иная проблема, чем то, что описано в статье. Я поправлю. Спасибо
Зачастую разного рода ошибки попадают в продакшн код, проходя ревью действительно опытных разработчиков. Наличие самого процесса код ревью, как и наличие тестов в коде, не гарантирует отсутствие ошибок в нем
Насколько я помню, такой подход был выбран из-за возможности избежать лишнего перемещения, когда сконструированный по-умолчанию объект класса std::thread заменяется только что созданным в теле конструктора. Но, конечно, вы правы, тут только такой подход позволил бы избежать UB
C++ все это позволяет в отличие от, например, Rust.
Если вы писали промышленный код на C++, то согласитесь со мной, что внимательное чтение учебников и документации все равно не спасает от подобных багов
Понимаю, что проблема синхронизации потоков имеет место во многих языках. C/C++ интересны тем, что их стандарты вводят определение Undefined Behavior. То есть стандарт прямо говорит, что в этой ситуации может произойти что угодно. В моем случае метод поиска в таблице не работал. Это выглядело интересно
Пишешь на плюсах неаккуратно - получаешь "ненормальное программирование" :)
Например, https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines