Почему определение `__cxa_throw` не вызывает ошибку ссылки?

Почему следующая программа на C++ не имеет конфликта ссылок с предоставленным системой __cxa_throw?

      #include <cstring>

void __cxa_throw(void *, void *, void (*)(void *)) {
    std::puts("bad luck");
}

int main() {
    throw 13;
}

Есть ли что-то магическое в этом символе? Для нормальной функции это было бы нарушением ODR, не так ли?

1 ответ

Как отметил @Igor, вам нужно добавить для предотвращения искажения имени.

Но причина, по которой это работает, заключается в том, что символ, скорее всего, определяется как слабый . Это означает, что если вы переопределите его, компоновщик будет использовать вашу версию вместо стандартной библиотеки.

Исходный код Gcc подтверждает, что они определяют его как слабый. Я не уверен в причине, возможно, какая-то внутренняя совместимость с разделяемыми библиотеками и тому подобное... На самом деле прямо над определением есть комментарий, который я почему-то пропустил:

      77 /* Everything from libstdc++ is weak, to avoid requiring that library
   to be linked into plain C applications using libitm.so.  */

Так вот причина.

Само собой разумеется, что это действительно ужасная идея, даже без надлежащей документации о том, что ожидают другие функции. сделать.

Другие вопросы по тегам