В последнее время я изучаю 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 ++ для выполнения типа punning. Если я правильно понимаю принцип, идея состоит в том, чтобы скопировать биты в область памяти, которая объявлена как правильный тип, и получить к ней доступ. Из небольшого исследования, которое я провел, оптимизирующие компиляторы хорошо идентифицируют эту идиому и поэтому довольно хорошо ее оптимизируют. Имейте в виду, некоторые детали ускользают от меня, потому что я не смог заставить это работать.
Тем не менее, мой реальный вопрос заключается в том, означает ли это, что большая часть стандартной библиотеки C не может быть на самом деле легально скомпилирована с использованием компилятора C ++ (то есть компилирует glibc с помощью g ++ вместо gcc)? Насколько я понимаю, компилятор может, например, исключить эти выражения, поскольку они вызывают неопределенное поведение?
Возможно, связано с этим вопросом:
Какова стоимость компиляции программы на C с помощью компилятора C ++?
Но я не уверен, что согласен с ответом. В случае, который я покажу выше, разве это не будет неопределенным поведением в C ++?