Разве memcpy не генерирует исключения?

Надеюсь, есть простой ответ на этот вопрос, поскольку он кажется простым, однако я не смог найти никакой информации об этом в Интернете.

В следующем фрагменте кода Visual Studio жалуется на недостижимый код в строке «удалить байты;»

try
{
   memcpy(bytes, other.bytes, count);
}
catch (...)
{
   delete[] bytes;
   throw;
}

Разве memcpy не генерирует исключения?


person mgray88    schedule 23.08.2011    source источник
comment
возможный дубликат возвращаемого значения c++ memcpy   -  person karlphillip    schedule 23.08.2011
comment
Между прочим, строка удаления байтов на самом деле должна быть байтами удаления [].   -  person Jack    schedule 23.08.2011
comment
Не обязательно - байты могут быть одной структурой...   -  person Michael Dorgan    schedule 23.08.2011
comment
В этом случае @Jack прав, нужно было удалить [], как я это пропустил?   -  person mgray88    schedule 23.08.2011
comment
@ mgray88: Затем вам следует отредактировать свой вопрос, чтобы исправить это.   -  person Serge Wautier    schedule 23.08.2011


Ответы (4)


Нет. memcpy — это функция C. Он не знает о функциях C++, таких как исключения. (Конечно, его вполне законно использовать в C++, хотя, возможно, это и не лучшая идея).

В ответ на karlphillip: я действительно должен прояснить свои мысли: в C++ memcpy следует использовать только для низкоуровневых буферных копий внутри частной реализации объекта. Его не следует использовать так обыденно, как это было в C (например, для копирования массивов чисел), потому что простые ванильные буферы теперь обычно скрыты внутри реализаций классов. Классы, оборачивающие массивы или другие большие объемы данных (например, std::array), предоставляют методы для управления их содержимым. И к тому времени, когда я пишу это, Марк Рэнсом прекрасно резюмировал это ;-)

person Serge Wautier    schedule 23.08.2011
comment
Мне кажется, или управление памятью действительно было проще до того, как начали появляться такие конструкции, как исключения и предотвращающие освобождение памяти? - person John; 23.08.2011
comment
Что бы вы использовали в C++ для копирования памяти из одного места в другое? - person karlphillip; 23.08.2011
comment
@karlphillip, в C++ вы пытаетесь не копировать память, а вместо этого копировать объекты; для этого вы используете std::copy. - person Mark Ransom; 23.08.2011
comment
@John: ручное управление ресурсами, безусловно, намного сложнее при наличии исключений, поэтому вам никогда не следует этого делать. В C++ все динамические ресурсы должны управляться объектами, которые освобождают их в своем деструкторе. Конечно, в некоторых языках есть исключения, но не детерминированное разрушение; используйте их на свой страх и риск. - person Mike Seymour; 23.08.2011
comment
@karlphillip Я видел довольно много ситуаций, когда использование std::copy для копирования памяти (то есть массива символов) было скомпилировано в более эффективный код, чем тот, который был предоставлен в memcpy() библиотеки C. - person Cubbi; 23.08.2011
comment
Я бы хотел увидеть это собрание. Я отчитаюсь, когда сделаю. - person karlphillip; 23.08.2011
comment
Люди используют C++ для написания низкоуровневого кода, например дисков устройств и встроенных систем, и когда они это делают, memcpy вполне разумно вызывать. - person Brian Neal; 23.08.2011

Ваш блок catch перехватывает исключения C++. На вашей платформе memcpy не определен для генерации исключений C++, и ваш компилятор знает об этом, поэтому он правильно информирует вас о том, что ваш блок catch никогда не будет выполняться.

Для memcpy разрешено создавать исключения C++. Поведение функции не определено для случаев, когда ни один из указателей не указывает на допустимый объект. Для функции вполне допустимо генерировать исключение C++ в этой ситуации, потому что неопределенное поведение означает, что она вполне может делать все.

Вы можете обнаружить, что memcpy на вашей платформе создает исключения ОС, когда вы читаете или записываете недействительную память. Вы можете получить нарушение прав доступа, но блок C++ catch не перехватывает такое исключение. Используйте для этого __try и __except. А еще лучше проанализируйте и отредактируйте свою программу, чтобы убедиться, что вы никогда не попадете в такую ​​ситуацию. Тогда вам не придется беспокоиться о том, как ведет себя та или иная платформа.

person Rob Kennedy    schedule 23.08.2011
comment
блок catch C++ не перехватывает такого рода исключения, если только вы не компилируете со злым, противным /EHa (на Visual C++). - person James McNellis; 23.08.2011

Нет, memcpy не генерирует исключений.

person Sean Bright    schedule 23.08.2011

memcpy исходит из C, который предшествует исключениям C++, так что нет. Вы никогда не поймаете исключение, вызванное memcpy.

person Daniel    schedule 23.08.2011