Я устанавливаю режим отладки в 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 перед #define). Почему это? Есть ли способ переключить режим отладки на другую строку программы (без флагов компилятора)? Я спрашиваю, потому что решаю проблемы на Leetcode.com, где я не могу передать флаги компилятора или изменить первую строку задачи.
@NeilButterworth Спасибо, это определенно не так, потому что проблема остается такой же, если я включаю только iostream и vector.
Пожалуйста, отредактируйте свой вопрос соответствующим образом.
@NeilButterworth Cm'on #define _GLIBCXX_DEBUG 1 #include <bits/stdc++.h> using namespace std;
, вероятно, худшее, что вы можете сделать.
Что касается вашего варианта использования, вы всегда можете скомпилировать и протестировать локально перед отправкой или использовать онлайн-среду, такую как Wandbox.
Если макрос влияет на поведение <vector>
, макрос необходимо установить так, как вам нужно, до #include <vector>
. Макрос не является глобальной настройкой — он влияет только на код, который впоследствии увидит компилятор. Вы можете отменить и переопределить макросы, используя #undef
и #define
, или проверить, определен ли макрос, используя #ifdef
, #ifndef
, #if defined()
и другие. Вкратце: прочитайте, как использовать препроцессор, ПРЕЖДЕ ЧЕМ просить помощи в его использовании.
Why does debug mode have to be set in first line?
Потому что это стандартные заголовки библиотеки, на которые влияет макрос. Если вы включите заголовки раньше, включенные определения не увидят определение макроса. Рассмотрим следующий пример и представьте, что это определение функции, включенное из стандартного заголовка:
#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
Is there a way to toggle debug mode on another line in the program (without compiler flags)?
Не после включения стандартных заголовков.
В этом случае вы можете использовать std::vector::at
вместо оператора индекса. Он будет диагностировать доступ за пределами границ даже без режима отладки.
Все, что начинается с #…
, является инструкцией для Препроцессор С++, которая запускает до фактический компилятор 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++ был предварительно обработан (т. е. все включено, условно развернуто и т. д.), вызывается фактический компилятор для сборки вашего кода.
Is there a way to toggle debug mode on another line in the program (without compiler flags)?
Измените значение этого флага во всем коде по мере необходимости.
«Изменяйте значение этого флага в коде по мере необходимости». Можете ли вы привести конкретный пример? В приведенном ниже ответе говорится, что это невозможно после включения стандартных заголовков, поэтому я не уверен, чему верить.
Попробуйте добавить #define _GLIBCXX_DEBUG 0
после к двум включенным? Однако в этот момент ваши определения векторов уже были включены с включенным кодом отладки.
@Jens, судя по вашему собственному ответу, это не работает, потому что препроцессор идет сверху вниз, выполняет включение, а затем определение, когда уже слишком поздно.
@user3586940 user3586940 Чего вы пытаетесь достичь? Установите _GLIBCXX_DEBUG
на 0
, если вы хотите отключить дополнительный отладочный код, установите его на 1
, если вам нужен дополнительный отладочный код в вашей программе. Но сделайте то, что до включает в себя…
@Jens Я нахожусь в среде, где хочу переключить режим отладки, но не могу изменить флаги компиляции или порядок включения стандартных заголовков. Кажется, нет никакого способа выполнить то, что я пытаюсь сделать.
@ user3586940, если вы хотите переключить режим отладки во время выполнения, то нет. Если вы хотите переключить режим отладки во время компиляции (т. е. внедрить код отладки в вашу программу или нет), вы можете сделать это, установив этот флаг препроцессора.
Я не верю, что это прямой обман stackoverflow.com/questions/31816095/…, поэтому я повторно открыл его. Но совет по этой ссылке по-прежнему актуален.