В последнее время я изучаю memmem, memcmp и другие подобные функции, чтобы научиться. Я взял исходный код glibc и скопировал файл, который мне нужно было изучить. Чтобы проверить реализацию, я написал небольшую функцию main и использую функцию, которую изучаю в этом main. Поскольку я в основном занимаюсь C++, я компилирую свой код с помощью компилятора C++ (clang ++, g ++). Он работает и дает правильные результаты.
То, что меня интересует, связано с псевдонимом типов. В коде есть места, где это происходит:
#define op_t unsigned long int;
inline int memcmp_common_alignment(
long int srcp1, long int srcp2, std::size_t len )
{
op_t a0, a1;
// some code
a0 = ( (op_t *) srcp1 )[0];
b0 = ( (op_t *) srcp2 )[0];
// rest of code
}
что, исходя из моего, возможно, ошибочного понимания, совпадает с:
inline int memcmp_common_alignment(
long int srcp1, long int srcp2, std::size_t len )
{
op_t a0, a1;
// some code
a0 = reinterpret_cast< op_t* >( srcp1 )[0];
b0 = reinterpret_cast< op_t* >( srcp2 )[0];
// rest of code
}
Мне кажется, что это неопределенное поведение в C++, потому что он считывает значение в srcp1 и srcp2 из другого типа. Это обсуждается, среди прочего, здесь и здесь.
Я думаю, что обычным "решением" этого является использование memcpy в C++ для обозначения типов. Если я правильно понимаю принцип, идея состоит в том, чтобы скопировать биты в область памяти, которая объявлена как правильный тип, и получить доступ к ней. Судя по небольшому исследованию, которое я провел, оптимизирующие компиляторы хорошо распознают эту идиому и поэтому достаточно хорошо ее оптимизируют. Имейте в виду, некоторые детали ускользают от меня, потому что я не смог заставить это работать.
Тем не менее, мой реальный вопрос больше в том, означает ли это, что большая часть стандартной библиотеки C не может быть легально скомпилирована с использованием компилятора C++ (то есть компиляции glibc с g ++ вместо gcc)? Насколько я понимаю, компилятор может, например, исключить эти выражения, поскольку они вызывают неопределенное поведение?
Вероятно, связано с этим вопросом: Какова стоимость компиляции программы C с помощью компилятора C++? Но я не уверен, что согласен с ответом. В случае, который я показал выше, разве это не было бы неопределенным поведением в C++?
Также обратите внимание: люди, пишущие реализацию, могут воспользоваться всеми видами зла, потому что они знают точно, как это неопределенное поведение проявится на целевой платформе. Вы часто будете видеть, как они выполняют трюки, которых следует избегать, как гласит здравый смысл.





Примечание. C и C++ - это разные языки очень, и хотя они имеют общее (сокращающееся) подмножество и некоторый общий синтаксис, они являются нет одинаковыми. И некоторые выражения являются действительными C и действительными C++, но имеют семантику разные, поэтому компиляция C с помощью компилятора C++ обязательно совпадает с нет компиляцией с помощью компилятора C, даже если это синтаксически корректно и компиляция завершается успешно, это может очень сильно отличаться. ну веди себя по другому.