Почему _GLIBCXX_DEBUG должен быть установлен в первой строке? - PullRequest
1 голос
/ 07 апреля 2019

Я устанавливаю режим отладки в gcc в следующей бесполезной программе:

#define _GLIBCXX_DEBUG 1
#include <vector>
#include <iostream>
using namespace std;
int main() {
    vector<int> v{1,2,3};
    for(int i=0; i<100000000000000;i++)
    cout<<v[i];
}

, и программа сообщает мне, что мой индекс выходит за границы.Однако, если я переверну порядок первых двух строк, я не получу такого сообщения об ошибке (#include before #define).Почему это?Есть ли способ переключить режим отладки на другую строку в программе (без флагов компилятора)?Я спрашиваю, потому что я решаю проблемы на Leetcode.com, где я не могу передать флаги компилятора или изменить первую строку проблемы.

Ответы [ 2 ]

3 голосов
/ 07 апреля 2019

Почему режим отладки должен быть установлен в первой строке?

Потому что это стандартные заголовки библиотеки, на которые влияет макрос.Если вы включите заголовки раньше, то включенные определения не увидят определения макроса.Рассмотрите следующий пример и представьте, что это определение функции, включенное в стандартный заголовок:

#define _GLIBCXX_DEBUG 1

inline void foo() {
#ifdef _GLIBCXX_DEBUG
    std::cout  << "debug mode is enabled";
#else
    std::cout  << "debug mode is not enabled";
#endif
}

против:

inline void foo() {
#ifdef _GLIBCXX_DEBUG
    std::cout  << "debug mode is enabled";
#else
    std::cout  << "debug mode is not enabled";
#endif
}

#define _GLIBCXX_DEBUG 1

Есть ли способ включить режим отладки надругая строка в программе (без флагов компилятора)?

Не после включения стандартных заголовков.

В этом случае вы можете использовать std::vector::at вместо оператора индекса.Он будет выполнять диагностику за пределами доступа даже без режима отладки.

2 голосов
/ 07 апреля 2019

Все, что начинается с #…, является инструкцией для препроцессора C ++ , который запускает до фактического компилятора C / C ++;препроцессор создает окончательный исходный код для компилятора.

Итак, вот что происходит, когда ваша программа компилируется.

Шаг первый: препроцесс

Препроцессор читает ваш код сверху внизи выполняет инструкции.

#define _GLIBCXX_DEBUG 1

Установите флаг с именем _GLIBCXX_DEBUG на 1.

#include <vector>
#include <iostream>

Считайте файл vector.h и iostream.h из того, что включает ваш компиляторпуть есть.Этот файл содержит больше кода C / C ++, а также инструкции препроцессора, которые теперь рекурсивно разворачиваются.Часть этого кода может выглядеть как

#if _CLIBCXX_DEBUG
prinf("Print me to debug!");
#endif

, и этот код появляется в вашем окончательном C / C ++.Если ваш _CLIBCXX_DEBUG равен 0, то кода там не будет.В результате вы можете собрать свой код перед его компиляцией.

В вашем случае этот дополнительный код добавляет специальные тесты в ваш окончательный файл C / C ++, которые вызывают появившееся сообщение об ошибке.Когда вы переключаете линии, флаг не будет установлен при обработке #include, поэтому эти специальные тесты не будут добавлены в ваш источник.

См. этот вопрос о том, каквыгрузить окончательный код C / C ++, который на самом деле компилируется.

Шаг второй: скомпилировать

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

Есть ли способ переключить режим отладки в другой строке программы (без флагов компилятора)?

Измените значение этого флага в коде, как вам нужно.

...