#c #gcc #linker #header-files
#c #gcc #компоновщик #заголовочные файлы
Вопрос:
Итак, мы используем #include
для указания компилятору / компоновщику, где найти весь соответствующий код для класса.
Взгляните на это:
ClassC.h:
#include "ClassA.h";
ClassD.h:
#include "ClassC.h"
Допустим, мы используем ClassA
в нашем ClassD
, но таким образом, который никоим образом не связан ClassC
с. Мы неявно включили его, включив ClassC
, поэтому ошибка не выдается. Однако, если код изменится и ClassC
больше не понадобится (и мы удалим #include "ClassC.h"
его из-за этого), мы получим неопределенную ошибку ссылки, поскольку ClassA
теперь на нее нет ссылок.
Есть ли способ заставить компилятор / компоновщик просматривать каждый из * .cpp и назначенный * .h независимо, не заглядывая во включенные файлы .h?
Если бы это было так, он бы не просматривал ClassC.h
и не видел, что он включает ClassA.h
, а выдавал ошибку или, по крайней мере, предупреждение, сообщающее мне, что я не включил ClassA.h
. Это имеет больше смысла, поскольку, насколько ClassD
известно классу, ClassA
они ClassC
не связаны друг с другом (в соответствии с установленным предположением, которое я использую ClassA
независимо ClassC
).
Я думаю, что код, написанный таким образом, был бы намного более стабильным и устойчивым к изменениям. Не так ли?
Кроме того, допустим, мы создаем проект, и он работает. Если бы мы затем ссылались на некоторый класс (X) раньше в коде, чем на него ссылались ранее, мы могли бы получить ошибку, если бы он использовал какой-то другой класс (Y), который был включен из какого-либо другого источника между этой точкой в программе и предыдущим первым появлением этого класса. Если бы мы более тесно привязали includes к каждому заголовочному файлу, который явно его использует, такие ошибки никогда бы не появились.
Я знаю, что мог бы отслеживать все это сам, но было бы так легко пропустить несколько или более в более крупных проектах, даже средних. Кроме того, наличие ошибки / предупреждения значительно упростило бы управление.
Я знаю, что немного все усложняю, но мне это кажется хорошей практикой.
Это даже хорошая идея, и может ли она каким-то образом быть установлена в параметрах компилятора / компоновщика (например, компилятор GNU gcc в CodeBlocks)?
Комментарии:
1. Вы должны проверить включение охранников. en.wikipedia.org/wiki/Include_guard
2. Я знаю, что защита включения великолепна и не позволяет вам включать одни и те же две вещи в проект. Я хочу иметь возможность включать что-то в свой код в 10 разных местах, если это необходимо, несмотря на то, что компилятор / компоновщик использует только первый, до которого он добирается.
3. Я не понимаю, ни какую проблему вы пытаетесь решить, ни решение, которое вы предлагаете
4. «хочу иметь возможность включать что-то в свой код в 10 разных местах» что мешает вам сделать это?
5. Я думаю, что суть вашей проблемы заключается в том, что вы без необходимости включаете заголовки в заголовки, а не в связанные файлы .cpp. Это может сэкономить некоторое время на вводе текста, но также приведет к одной из форм спагетти.
Ответ №1:
Допустим, мы используем ClassA в нашем ClassD, но таким образом, который никоим образом не связан с ClassC. Мы неявно включили его, включив ClassC, поэтому ошибка не выдается. Однако, если код изменится и ClassC больше не понадобится (и мы удалим #include «ClassC.h» из-за этого), мы получим неопределенную ошибку ссылки, поскольку ClassA теперь не ссылается.
Если вам нужно использовать ClassA
в вашем ClassD
, то явно #include "ClassA.h"
в вашем ClassD.h
. Не полагайтесь на неявные цепочки включений.
Комментарии:
1. Я хочу это сделать. Я просто хочу знать, есть ли способ для компилятора выполнить проверку для меня.
2. @Karlovsky120: На данный момент я не знаю, что вы точно имеете в виду. Компилятор не обладает экстрасенсорными способностями, чтобы угадать, какие заголовки вам нужны. В любом случае, если вы не включите требуемые заголовки, вы получите ошибки компилятора или компоновщика.
3. Я в основном имел в виду, может ли компилятор / компоновщик определить, было ли включение явным или неявным, и выдать предупреждение о том, что это было неявное включение. Это может быть сложно сделать, поскольку некоторые неявные включения (например, унаследованные от родительского класса) будут в порядке, поскольку они всегда будут присутствовать.
4. @Karlovsky120 Таким образом, вы имеете в виду, что используете класс X, но напрямую не включаете его заголовок и полагаетесь на неявные цепочки включения. Я не знаю, есть ли такой инструмент, доступный сегодня.
5. Сейчас я провел некоторое исследование, и некоторые статические анализаторы кода, похоже, проверяют это. Я забыл, какие именно.