Я использовал в своем коде класс исключения std::invalid_argument. Поэтому я также включил заголовок <exception> в предварительно скомпилированный заголовок (pch.h в моем случае). Но затем я удалил <exception> из pch.h и код успешно скомпилирован на GCC 11.2, и я был удивлен.

Вот некоторые примеры:

#include <exception> // removing this does not have any effects
#include <array> // the same here
.
.
.
throw std::invalid_argument( exceptionMsg ); // somewhere in the code
.                                            // how does this work?
.
.
std::array<int, 4> buffer { }; // somewhere in the code
.                              // how does array work without #include <array> ??
.
.

Точно так же я удалил <iterator>, <array>, <cstring> и т. Д. Из pch.h и все еще без проблем. Как это возможно?

Итак, если включение заголовков не поможет при компиляции кода, то какова их цель? Безопасно ли удалить эти #include, если компилятор не жалуется?

-1
digito_evo 27 Ноя 2021 в 21:52
2
Стандартные заголовки могут включать другие стандартные заголовки, это зависит от реализации. Всегда включайте необходимые заголовки. Также у вас могут возникнуть проблемы с перестройкой, попробуйте выполнить полную очистку между тестами. Нам нравится видеть минимально воспроизводимый пример, чтобы мы могли сами проверить любые проблемы. Как вы используете предварительно скомпилированные заголовки с GCC, имя файла pch.h обычно используется в MSVC для предварительно скомпилированных заголовков?
 – 
Richard Critten
27 Ноя 2021 в 21:54
2
К вашему сведению, std::invalid_argument определяется в <stdexcept>, а не в <exception>
 – 
Remy Lebeau
27 Ноя 2021 в 22:00

1 ответ

Лучший ответ

Но затем я удалил pch.h, и код успешно скомпилирован на GCC 11.2, и я был удивлен.

В этом нет ничего необычного. Вы к этому привыкнете.

Как это возможно?

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

Безопасно ли удалять эти #includes, если компилятор не жалуется?

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

3
eerorika 27 Ноя 2021 в 21:57
Есть ли способ проверить, включены ли все необходимые заголовки? Или все сложнее?
 – 
digito_evo
27 Ноя 2021 в 22:11
Прочтите все идентификаторы, которые вы используете, проверьте документацию, где они объявлены / определены, и проверьте, включили ли вы это или нет. Шаги просты, но это большая работа, если вы не можете запомнить много идентификаторов.
 – 
eerorika
27 Ноя 2021 в 22:13
Понятно. Другой вопрос: исправил ли modules в C ++ 20 эти проблемы?
 – 
digito_evo
27 Ноя 2021 в 22:16
1
Модули должны позволять избежать проблемы. Но это ничего не решит, пока все, что вы используете, не будет модульным. А поскольку стандартная библиотека в C ++ 20 не является модульной, это, в частности, не решено.
 – 
eerorika
27 Ноя 2021 в 22:18
Это грустно. Я надеюсь, что они полностью реализуют его до того, как выйдет C ++ 23.
 – 
digito_evo
27 Ноя 2021 в 22:22