#include заголовки в C / C ++ - PullRequest
       24

#include заголовки в C / C ++

6 голосов
/ 22 марта 2010

После прочтения нескольких вопросов, касающихся проблем с компиляцией (особенно C ++) и замечая, что во многих случаях проблема заключается в отсутствующем заголовке #include.Я не мог не задаться вопросом в своем невежестве и спросить себя (и теперь для вас):

Почему пропущенные заголовки не проверяются автоматически и не добавляются или не запрашиваются у программиста?

Такая функция доступна, например, для операторов импорта Java в Netbeans.

Ответы [ 9 ]

12 голосов
/ 22 марта 2010

Помните конфликт в Java между java.util.Date и java.sql.Date?Если кто-то использует Date в своем коде, вы не можете сказать, забыли ли они import java.util.Date или import java.sql.Date.

В Java и C ++ невозможно с уверенностью сказать, что импортировать / включатьзаявление отсутствует.Так что ни один язык не пытается.В вашей среде IDE могут быть предложены необъявленные символы, используемые в вашем коде.

Эта проблема еще более усложняется в C ++, поскольку стандарт говорит, что любой стандартный заголовок может включать любые другие стандартные заголовки.Поэтому очень легко использовать функцию или класс без непосредственного включения заголовка, который его определяет, потому что ваш компилятор случайно включает правильный заголовок.Результирующий код работает в некоторых реализациях, но не в других, в зависимости от того, разделяют ли они эту зависимость заголовка.

Как правило, в IDE C ++ невозможно определить, является ли зависимость заголовка "гарантированной" или просто случайнойдетали реализации, на которые пользователи не должны полагаться.Очевидно, что для стандартных библиотек он может просто знать, что определено в каких заголовках, но как только вы попадаете в сторонние библиотеки, это становится довольно неопределенным.

Я думаю, что большинство программистов на C ++ ожидают, что заголовки определяют, что и какие заголовки определяютсимволы.В Java правило «один открытый класс для файла» значительно упрощает это, и вы просто импортируете нужные вам пакеты / классы.В C ++ нет пакетов, и единственный способ для IDE найти класс с именем my_namespace::something::MyClass - найти его в каждом заголовочном файле.

7 голосов
/ 22 марта 2010

Почему отсутствующие заголовки не проверяются автоматически и не добавляются или не запрашиваются программисту?

Но они автоматически проверяются.

  1. Мой компилятор терпит неудачу при компиляции, когда не может найти заголовок.
  2. Моя IDE (eclipse) добавляет визуальную подсказку, когда не может найти заголовочный файл, который я включил, # подчеркивает строку #include и предоставляет всплывающую подсказку, сообщающую мне, в чем проблема.

Он не будет автоматически добавлять включение, потому что не может знать, какое включение я забыл. Компиляторы не экстрасенсы.

4 голосов
/ 22 марта 2010

Последнее, что я помню, Java также выдает ошибку, если пропущен оператор Import.Графический интерфейс NetBeans делает вашу жизнь проще.

Возможно, вам следует попытаться найти интеллектуальный графический интерфейс для вашего кода C / C ++.

2 голосов
/ 22 марта 2010

Если я ссылаюсь на функцию с именем sqrt, как компилятор узнает, какой файл искать, если я его не указал? Это может быть абсолютно любой файл на моем жестком диске.

В отличие от Java, C ++ на самом деле не считает какие-либо файлы «специальными». В Java есть гигантская (раздутая) библиотека классов, которая автоматически становится доступной для программиста.

В C ++ эта концепция не существует. Вы указываете компилятору, в каких путях искать, и всякий раз, когда вы #include файла, он будет искать имя файла в этих путях.

Если это произойдет, чтобы найти стандартный файл библиотеки, он будет использовать это. Если случится найти сторонний файл, он будет его использовать.

Компилятор не знает , что sqrt определено в заголовке math.h. Или что также , как правило, определяется в cmath На самом деле функции, определенные в заголовке, могут варьироваться . Возможно, если я # определю соответствующий символ препроцессора, некоторые функции будут удалены из определенного заголовка, а другие будут включены.

Но в отличие от Java, где функции и классы, определенные библиотекой, могут быть определены только путем изучения метаданных файла библиотеки, в C ++ должен быть скомпилирован заголовок. И результат его компиляции может варьироваться в зависимости от контекста, в который он включен.

Таким образом, компилятор C ++ не может угадать, какой заголовок должен быть включен для определения функции, которую вы только что использовали.

2 голосов
/ 22 марта 2010

Поскольку в секунду, когда вы доверяете компьютеру , думаете, для вас, у вас в руках крупный случай SkyNet.

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

1 голос
/ 22 марта 2010

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

В C или C ++ имя, которое вы даете заголовку, совсем не обязательно должно соответствовать содержимому. Если вы хотите достаточно сильно, вы можете назвать свои заголовки 1.h, 2.h, 3.h и т. Д. - или даже 1.bas, 2.pas, 3.java, 4.ada и любые другие вводящие в заблуждение имена, которые вы предпочитаете. Очевидно, это плохая идея, но если бы вы все-таки сделали это, компилятор не стал бы беспокоиться.

Таким образом, инструменту C или C ++ гораздо сложнее угадать, какой заголовок необходимо включить, чтобы получить определение определенного типа. Теоретически, он может (например) создать большую базу данных всех функций, классов, типов и т. Д. Во всех заголовках, которые вы написали, и когда вы их используете, скажете, какие заголовки определяют какие имена , но я не знаю об IDE, которая действительно так делает.

1 голос
/ 22 марта 2010

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

0 голосов
/ 22 марта 2010

Поскольку в общем случае сложно определить, какие заголовочные файлы нужно включить, чтобы что-то правильно определить.Было бы неплохо, если бы ваша IDE могла угадывать простые случаи и предлагать помощь.

0 голосов
/ 22 марта 2010

NetBeans - это интегрированная среда разработки (IDE). Некоторые C / C ++ IDE действительно имеют эту функцию ... но не все знают об этом или используют ее.

...