Почему C++Builder не может создать предварительно скомпилированные заголовки?
проблема
В CodeGear C++Builder 2009 мы используем предварительно скомпилированный заголовок, чтобы значительно сократить время компиляции. У нас один и тот же заголовочный файл, который внедряется в несколько проектов. При компиляции некоторых проектов компилятор выдает следующее предупреждение:
[BCC32 Warning] Dateutils.hpp(43): W8058 Cannot create pre-compiled header: initialized data in header
В этом примере Dateutils.hpp - это файл, на который он жалуется (заголовок CodeGear). Я видел это и с другими заголовками. Что делает это интересным, так это то, что это происходит только с некоторыми проектами (вводится тот же заголовок).
В прошлом мне нужно было просто найти заголовок, который в конечном итоге включил этот ошибочный файл, и удалить его из моего предварительно скомпилированного заголовочного файла. Кто-нибудь знает, что здесь происходит и лучший способ это исправить?
Обновить
В итоге я выполнил процедуру исключения из заголовочного файла и нашел интересную находку, которую я не могу объяснить. Из 50+ заголовков, которые включены, когда я удалил vcl.h, я больше не получаю предупреждения W8058. Я не понимаю этого, так как представляю, что этот заголовочный файл, в частности, является основным кандидатом на предварительную компиляцию. Кто-нибудь может это объяснить?
4 ответа
Одна вещь, которая может быть связана с этим, - то, как строковые параметры по умолчанию обрабатываются BCB 200x.
Функции, объявленные таким образом, дают сообщение "не может сгенерировать предварительно скомпилированный заголовок".
void myFunc(const AnsiString ¶m="");
Однако, измените его на это, и скомпилированный заголовок может быть сгенерирован.
void myFunc(const AnsiString ¶m = AnsiString(""));
По моему опыту, это предупреждение вводит в заблуждение. Кажется, что компилятор определяет "кандидатов", где заголовок мог инициализировать данные, а затем, когда он определяет, что файл на самом деле в порядке, он продолжается. Если он не найдет другого кандидата, он не покажет сообщение. Если он находит другого кандидата, который оказывается реальной проблемой, он затем показывает сообщение о первом кандидате.
Это делает выявление реального виновника чрезвычайно трудным.
Есть заголовочные файлы VCL, которые имеют эту известную проблему: QC 23002. Отмеченная серьезность на этом пункте, тем не менее, является "незначительным отказом".
Таким образом, варианты обхода ограничены:
- Not using those header files (which, yes, does defeat the idea)
- Изменить заголовочные файлы (не рекомендуется - сложно отслеживать изменения, сохранять их актуальность).
В любом случае, убедитесь, что из тех, с которыми вы сталкиваетесь, CodeGear знает об этих заголовочных файлах, имеющих эту проблему. Это, безусловно, будет лучшим способом решения этой проблемы в долгосрочной перспективе - пусть поставщик решит свою проблему. Предположительно, CodeGear имеет DateUtils.hpp в своих внутренних тестах для этого, но это было опубликовано (для QC 2781) в июле 2007 года. Если проблема или определенные заголовочные файлы значительно повлияли на вас, свяжитесь с ними по этому поводу.
Я получаю это предупреждение, когда код показывает:
#include <vcl.h>
#pragma hdrstop
Я нашел простое решение, поменяв эти строки на:
#pragma hdrstop
#include <vcl.h>
Предупреждение больше не появляется.