После чтения нескольких вопросов относительно проблем с компиляцией (особенно C++) и замечающий, что во многих случаях проблемой является недостающий заголовок #include. Я не мог помочь задаться вопросом в своем незнании и спросить меня (и теперь Вам):
Почему недостающие заголовки автоматически не проверяют и добавляют или требуют программисту?
Такая функция доступна для операторов импорта Java в Netbeans, например.
Помните конфликт в Java между java.util.Date
и java.sql.Date
? Если кто-то использует в своем коде Date
, вы не сможете сказать, забыли ли они import java.util.Date
или import java.sql.Date
.
И в Java, и в C ++ невозможно с уверенностью сказать, какой оператор импорта / включения отсутствует. Так что ни один язык не пытается. Ваша IDE может предлагать необъявленные символы, используемые в вашем коде.
Проблема еще более усложняется в C ++, потому что стандарт говорит, что любой стандартный заголовок может включать в себя любой другой стандартный заголовок (и). Поэтому очень легко использовать функцию или класс без прямого включения определяющего их заголовка, потому что ваш компилятор косвенно включает правильный заголовок. Результирующий код работает в некоторых реализациях, но не работает в других, в зависимости от того, разделяют ли они эту зависимость заголовка.
Как правило, в среде C ++ IDE невозможно определить, является ли зависимость заголовка «гарантированной» или это просто случайная деталь реализации, на которую пользователям не следует полагаться. Очевидно, что для стандартных библиотек он может просто знать, что определено в каких заголовках, но как только вы перейдете к сторонним библиотекам, это станет довольно неопределенным.
Я думаю, что большинство программистов на C ++ ожидают, что им придется искать, какие заголовки и какие символы определяют. В Java правило «один открытый класс для каждого файла» значительно упрощает это, и вы просто импортируете нужные пакеты / классы. В C ++ нет пакетов, и для среды IDE единственный способ найти класс с именем my_namespace :: something :: MyClass
- это искать его в каждом файле заголовка.
Отчасти разница связана с несколькими фундаментальными проектными решениями, которые были приняты по-разному между ними. В частности, Java требует, чтобы имя класса соответствовало имени файла, поэтому имя используемого вами класса в значительной степени указывает на то, что вам нужно импортировать.
В C или C ++ имя, которое вы даете заголовку, вовсе не обязательно должно совпадать с содержимым. Если вы очень хотите, вы можете назвать свои заголовки 1.h, 2.h, 3.h и так далее - или даже 1.bas, 2.pas, 3.java, 4.ada и т. Д. вводящие в заблуждение имена, которые вы предпочитаете. Очевидно, это плохая идея, но если бы вы все равно это сделали, компилятор бы это не беспокоило.
Таким образом, инструменту C или C ++ гораздо труднее угадать, какой заголовок нужно включить, чтобы получить определение конкретного типа. Теоретически он может (например) создать большую базу данных всех функций, классов, типов и т. Д. Во всех написанных вами заголовках, и когда вы его используете, сообщать вам, какие заголовки определяют, какие имена , но я не знаю IDE, которая действительно это делает.
Поскольку в тот момент, когда вы доверяете компьютеру думать за вас, у вас на руках оказывается серьезный случай SkyNet.
Компьютеры, в общем, очень плохо делают выбор, за исключением очень простых. Вытаскивать что-то из ада зависимостей просто не та задача, которую вы должны ему доверять, потому что такое мышление ведет к небрежному кодированию и ошибочному коду.
NetBeans - это IDE (интегрированная среда разработки). Некоторые IDE C / C ++ имеют эту функцию ... но не все знают об этом или используют ее.
Почему отсутствующие заголовки не проверяются автоматически и не добавляются или не запрашиваются программистом?
Но они автоматически проверяются.
Он не будет автоматически добавлять включение, потому что не может знать, какое включение я забыл. Составители не экстрасенсы.
Компилятор не должен думать за вас. Что если в двух разных библиотеках есть одноименная функция? Как он узнает, какой заголовок включать и с какой библиотекой компоновать? То, что компилятор или IDE молча исправляют ваш неаккуратный код, на мой взгляд, плохая идея.
Потому что, как правило, сложно понять, какие файлы заголовков нужно включить, чтобы что-то правильно определить. Было бы неплохо, если бы ваша IDE могла угадывать простые случаи и предлагать помощь.
Если я ссылаюсь на функцию с именем sqrt
, как компилятор узнает, в каком файле искать, если я его не указал? Это может быть абсолютно любой файл на всем моем жестком диске.
В отличие от Java, C ++ не считает какие-либо файлы «особенными». В Java есть гигантская (раздутая) библиотека классов, которая автоматически становится доступной для программиста.
В C ++ такой концепции не существует. Вы указываете компилятору, по каким путям искать, и всякий раз, когда вы #include файл, он будет искать имя файла в этих путях.
Если это произойдет, чтобы найти файл стандартной библиотеки, он будет использовать его. Если случится найти сторонний файл, он воспользуется им.
Компилятор не знает , что sqrt
определен в заголовке math.h
. Или что он также обычно определяется в cmath
На самом деле функции, определенные заголовком, могут различаться . Возможно, если я # определю соответствующий символ препроцессора, некоторые функции будут удалены из определенного заголовка, а другие будут включены.
Но в отличие от Java, где функции и классы, определенные библиотекой, можно определить, просто изучив метаданные файла библиотеки, в C ++ заголовок должен быть скомпилирован. И результат его компиляции может варьироваться в зависимости от контекста, в который он включен.
Таким образом, компилятор C ++ не может угадать, какой заголовок следует включить, чтобы определить функцию, которую вы только что использовали.
Насколько я помню, Java также выбрасывает ошибку, если пропущен оператор Import. Это графический интерфейс NetBeans, который облегчает вам жизнь.
Возможно, вам стоит попробовать найти интеллектуальный графический интерфейс для вашего кода на C/C++.