Size: a a a

2020 December 15

AF

Aidar Fattakhov in pro.cxx
источник

m

magras in pro.cxx
Aidar Fattakhov
В си++ и это уб
Так это детали реализации winapi, пользователя winapi это не затрагивает.
источник

m

magras in pro.cxx
Ignat Loskutov
`DRIVE_LAYOUT_INFORMATION_EX *` на хипе?
Если речь о new DRIVE_LAYOUT_INFORMATION_EX, то это не решение, так как api будет писать за границами объекта.
источник
2020 December 16

D

Dmitriy in pro.cxx
magras
Если речь о new DRIVE_LAYOUT_INFORMATION_EX, то это не решение, так как api будет писать за границами объекта.
Речь не об этом, конечно же
источник

D

Dmitriy in pro.cxx
Речь о выделении буфера в строке, полагая, что на целевых системах __STDCPP_DEFAULT_NEW_ALIGNMENT__ не будет меньше 8.
источник

D

Dmitriy in pro.cxx
И понятно, что буфер будет выделяться с учётом ответа от драйвера - как MS завещала...
источник

m

magras in pro.cxx
По идее правильное решение использовать placement new перед вызовом winapi, чтобы корректно прочитать DRIVE_LAYOUT_INFORMATION_EX. А для того чтобы прочитать все остальное формально надо изголяться с чем-нибудь вроде bit_cast, который работает через копирование. Других честных решений я не придумал.
источник

D

Dmitriy in pro.cxx
magras
По идее правильное решение использовать placement new перед вызовом winapi, чтобы корректно прочитать DRIVE_LAYOUT_INFORMATION_EX. А для того чтобы прочитать все остальное формально надо изголяться с чем-нибудь вроде bit_cast, который работает через копирование. Других честных решений я не придумал.
Чисто теоретически, можно использовать placement new для DRIVE_LAYOUT_INFORMATION_EX и потом до конца буфера - для PARTITION_INFORMATION_EX, которые идут хвостиком
Но выглядит странновато
источник

D

Dmitriy in pro.cxx
Другой вопрос... А насколько здесь - с учётом вышеупомянутых гарантий ABI - вообще нужно пресловутое "полностью честное" решение?
источник

m

magras in pro.cxx
Dmitriy
Чисто теоретически, можно использовать placement new для DRIVE_LAYOUT_INFORMATION_EX и потом до конца буфера - для PARTITION_INFORMATION_EX, которые идут хвостиком
Но выглядит странновато
А, если можно до вызова winapi понять сколько и какого типа будут объекты в хвосте, да их можно создать вместе с заголовком. Это я не сообразил.
источник

m

magras in pro.cxx
Кстати этот [1] внезапно может все инвалидировать, потому что он приводит к тому, что объекты пересекаются между собой. Никогда не задумывался об этом.
источник

D

Dmitriy in pro.cxx
magras
А, если можно до вызова winapi понять сколько и какого типа будут объекты в хвосте, да их можно создать вместе с заголовком. Это я не сообразил.
Тип известен, сколько - там танцы, конечно, ибо DeviceIoControl не позволит получить число объектов сразу, придется её (по рекомендации с MSDN) вызывать в цикле, удваивая размер буфера. Вопрос целесообразности остаётся открытым
источник

D

Dmitriy in pro.cxx
magras
Кстати этот [1] внезапно может все инвалидировать, потому что он приводит к тому, что объекты пересекаются между собой. Никогда не задумывался об этом.
Не понял, как они пересекаются
источник

m

magras in pro.cxx
Dmitriy
Не понял, как они пересекаются
Да, я не прав. Я подозревал что там char[1]. Но там PARTITION_INFORMATION_EX PartitionEntry[1];
источник

m

magras in pro.cxx
Dmitriy
Тип известен, сколько - там танцы, конечно, ибо DeviceIoControl не позволит получить число объектов сразу, придется её (по рекомендации с MSDN) вызывать в цикле, удваивая размер буфера. Вопрос целесообразности остаётся открытым
В принципе если нам известен размер буфера вероятно количество объектов в хвосте можно вычислить примерно так: (size - sizeof(_DRIVE_LAYOUT_INFORMATION_EX)) / sizeof(PARTITION_INFORMATION_EX)

А так я люблю порассуждать о UB, потому что стараюсь писать портируемый код. Но если приходится пользоваться низкоуровневыми штуками специфичными для платформы, я готов гораздо больше полагаться на особенности реализации.
источник

D

Dmitriy in pro.cxx
magras
В принципе если нам известен размер буфера вероятно количество объектов в хвосте можно вычислить примерно так: (size - sizeof(_DRIVE_LAYOUT_INFORMATION_EX)) / sizeof(PARTITION_INFORMATION_EX)

А так я люблю порассуждать о UB, потому что стараюсь писать портируемый код. Но если приходится пользоваться низкоуровневыми штуками специфичными для платформы, я готов гораздо больше полагаться на особенности реализации.
Судя по особенностям реализации и ABI (и тому, как это делают в примерах на MSDN и OSR), можно вообще забить на инициализацию объектов в строке, если с выравниванием всё хорошо...
источник

D

Dmitriy in pro.cxx
Хотя с точки зрения С++ это будет прогулка под ручку с UB
источник

m

magras in pro.cxx
Dmitriy
Судя по особенностям реализации и ABI (и тому, как это делают в примерах на MSDN и OSR), можно вообще забить на инициализацию объектов в строке, если с выравниванием всё хорошо...
Вероятно их примеры написаны на чистом си, где это окей. Но я не знаю чистый си.
источник

D

Dmitriy in pro.cxx
magras
Вероятно их примеры написаны на чистом си, где это окей. Но я не знаю чистый си.
Да, в чистом Си это окей
Задумался: драйвер внутри юзает RtlCopyMemory, а в текущей реализации это std::memcpy => в C++20 считается инициализацией для trivially_copyable типов, в более ранних - формально UB, но работает
источник

A

Alex in pro.cxx
А есть в std функция, которая сделает move, если аргумент lvalue (или rvalue reference), и просто передаст дальше, если lvalue ссылка? Типа forward, но с добавлением случая для lvalue.
источник