Почему нет предупреждения компоновщика для смешивания -fexceptions и -fno-excptions - PullRequest
0 голосов
/ 21 декабря 2018

Я удивлен, что от компилятора нет предупреждения о компиляторе для смешивания -fexceptions и -fno-excptions или специально для смешивания кода с таблицами и без них.Я понимаю, что могут существовать бесконечные законные и / или неконтролируемые способы оказаться в этом состоянии, но я бы предпочел получить раньше std :: terminate (), чем ( установка скучного теста следует ):

runner.cpp

extern void testA();

int main() {
    try {
        testA();
    } catch (...) {}
}

testA.cpp

#include <iostream>
extern void testB();

struct resA {
    ~resA() { std::cout << "release resA" << std::endl; }
};

void testA() {
    resA a;
    testB();
}

testB.cpp

#include <iostream>
struct resB {
    ~resB() { std::cout << "release resB" << std::endl; }
};

void testB() {
    resB b;
    throw 42;
}

Давайте скомпилируем a.cpp без исключения, но остальные с исключениями, также свяжите все это вместе с исключениями:

clang++ -Wall -Wextra -Wpedantic -O3 -std=c++1z a.cpp -fno-exceptions -c clang++ -Wall -Wextra -Wpedantic -O3 -std=c++1z b.cpp test.cpp -fexceptions -c clang++ -Wall -Wextra -Wpedantic -O3 -std=c++1z a.o b.o test.o -fexceptions

Выход: release resB

Мы 'эффективно утечка ресурса A, может быть, огромного, и никто не заметил, что мы можем продолжать работать

Когда все скомпилировано с такими же флагами, все ресурсы очищаются, как и ожидалось, потому что все размотки выполняются правильно

В этом случае даже пометка testA как noexcept не приводит к завершению, когда 'потенциально выбрасывающий' testB бросает

1 Ответ

0 голосов
/ 21 декабря 2018

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

Кроме того, код может быть скомпилирован без исключения для поддержки раскрутки, но с полной (дажеасинхронные) таблицы раскручивания.Эти таблицы используются не только реализацией C ++ для разматывания стека, но и средствами отладки и производительности.Наличие таблицы для получения точных стековых трассировок без необходимости установки отладочной информации обеспечивает существенную ценность независимо от языка программирования или используемого подмножества языка.Вот почему некоторые дистрибутивы GNU / Linux компилируют все двоичные файлы таким образом (включая программы на C), несмотря на размерные издержки, которые возникают.

Но вы правы, лучшая диагностика цепочки инструментов стоит того.Проект annobin пытается собрать много проверок для рекомендованных флагов сборки, но в настоящее время он не охватывает информацию о раскрутке.Он проверяет -fexceptions, потому что это в значительной степени требует усиления даже для кода C, если вы когда-либо используете обработчики отмены потоков POSIX (без фактического отмены), из-за GCC PR 61118 .Но здесь определенно есть место для лучшей диагностики.Это то, что примечания к свойствам GNU HJ LU тоже могут охватывать.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...