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

Я устанавливаю режим отладки в 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, где я не могу передать флаги компилятора или изменить первую строку задачи.

Я не верю, что это прямой обман stackoverflow.com/questions/31816095/…, поэтому я повторно открыл его. Но совет по этой ссылке по-прежнему актуален.

user2100815 07.04.2019 02:30

@NeilButterworth Спасибо, это определенно не так, потому что проблема остается такой же, если я включаю только iostream и vector.

user3586940 07.04.2019 02:31

Пожалуйста, отредактируйте свой вопрос соответствующим образом.

user2100815 07.04.2019 02:32

@NeilButterworth Cm'on #define _GLIBCXX_DEBUG 1 #include <bits/stdc++.h> using namespace std;, вероятно, худшее, что вы можете сделать.

πάντα ῥεῖ 07.04.2019 02:33

Что касается вашего варианта использования, вы всегда можете скомпилировать и протестировать локально перед отправкой или использовать онлайн-среду, такую ​​​​как Wandbox.

chris 07.04.2019 02:33

Если макрос влияет на поведение <vector>, макрос необходимо установить так, как вам нужно, до #include <vector>. Макрос не является глобальной настройкой — он влияет только на код, который впоследствии увидит компилятор. Вы можете отменить и переопределить макросы, используя #undef и #define, или проверить, определен ли макрос, используя #ifdef, #ifndef, #if defined() и другие. Вкратце: прочитайте, как использовать препроцессор, ПРЕЖДЕ ЧЕМ просить помощи в его использовании.

Peter 07.04.2019 03:24

Есть еще одно определение, которое может быть применимо к std::vector: _GLIBCXX_SANITIZE_VECTOR.

jww 16.06.2019 21:43
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
2
7
2 299
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

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)?

Измените значение этого флага во всем коде по мере необходимости.

«Изменяйте значение этого флага в коде по мере необходимости». Можете ли вы привести конкретный пример? В приведенном ниже ответе говорится, что это невозможно после включения стандартных заголовков, поэтому я не уверен, чему верить.

user3586940 07.04.2019 02:42

Попробуйте добавить #define _GLIBCXX_DEBUG 0после к двум включенным? Однако в этот момент ваши определения векторов уже были включены с включенным кодом отладки.

Jens 07.04.2019 02:44

@Jens, судя по вашему собственному ответу, это не работает, потому что препроцессор идет сверху вниз, выполняет включение, а затем определение, когда уже слишком поздно.

chris 07.04.2019 02:46

@user3586940 user3586940 Чего вы пытаетесь достичь? Установите _GLIBCXX_DEBUG на 0, если вы хотите отключить дополнительный отладочный код, установите его на 1, если вам нужен дополнительный отладочный код в вашей программе. Но сделайте то, что до включает в себя…

Jens 07.04.2019 02:48

@Jens Я нахожусь в среде, где хочу переключить режим отладки, но не могу изменить флаги компиляции или порядок включения стандартных заголовков. Кажется, нет никакого способа выполнить то, что я пытаюсь сделать.

user3586940 07.04.2019 02:50

@ user3586940, если вы хотите переключить режим отладки во время выполнения, то нет. Если вы хотите переключить режим отладки во время компиляции (т. е. внедрить код отладки в вашу программу или нет), вы можете сделать это, установив этот флаг препроцессора.

Jens 07.04.2019 02:51

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