How to avoid the error message : "Cannot open include file: 'stdafx.h': No such file or directory"?
This message appears during the compilation of Microsoft Visual® C++ code generated by IBM Rational® Rose®: «Cannot open include file: ‘stdafx.h’: No such file or directory»?
Cause
As the error message says, the compiler is finding an include statement for the header file "stdafx.h", but can’t find the file itself.
Rose is generating the following line: #include "stdafx.h" by default.
The file stdafx.h is usually used as a precompiled header file. Precompiled headers help to speed up compilation when a group of files in a project do not change.
Resolving The Problem
If a precompiled header is not used, this include shouldn’t get generated in the code. To turn it off, open the Visual C++ Component Properties dialog and in the tab "Includes" delete the text in the "Initial Source Includes".
Another possibility is to create an empty "stdafx.h" file.
For more information about precompiled header files, refer to the Microsoft knowledge base.
0.8 – Несколько распространенных проблем C++
В этом разделе мы рассмотрим некоторые из распространенных проблем, с которыми, похоже, начинающие программисты сталкиваются с довольно высокой вероятностью. Это не исчерпывающий список проблем компиляции или запуска программ, а скорее прагматичный список решений самых основных проблем. Если у вас есть предложения по другим вопросам, которые могут быть добавлены в этот список, опубликуйте их в разделе комментариев ниже.
Общие проблемы во время выполнения
Вопрос: При выполнении программы окно консоли мигает, а затем сразу закрывается.
Сначала добавьте или убедитесь, что следующие строки находятся в верхней части вашей программы (пользователи Visual Studio должны убедиться, что эти строки появляются после #include "pch.h" или #include "stdafx.h" , если таковые существуют):
Во-вторых, добавьте следующий код в конец функции main() (прямо перед оператором return ):
Это заставит вашу программу ждать, пока пользователь нажмет любую клавишу, прежде чем продолжить, что даст вам время изучить вывод вашей программы, прежде чем ваша операционная система закроет окно консоли.
Другие решения, такие как обычно предлагаемое system("pause") , могут работать только в определенных операционных системах, и их следует избегать.
Более старые версии Visual Studio могут не приостанавливаться, когда программа запускается в режиме Начать с отладкой (Start With Debugging) ( F5 ). Попробуйте запустить в режиме Начать без отладки (Start Without Debugging) ( Ctrl + F5 ).
Вопрос: Я запустил свою программу, получил окно, но ничего не выводится.
Выполнение может блокировать ваш антивирус. Попробуйте временно отключить его и посмотрите, не в этом ли проблема.
Вопрос: Моя программа компилируется, но работает некорректно. Что не так?
Отладьте ее! Советы по диагностике и отладке программ приведены далее в главе 3.
Общие проблемы времени компиляции
Вопрос: Когда я компилирую свою программу, я получаю ошибку о неразрешенном внешнем символе _main или _WinMain@16
Это означает, что ваш компилятор не может найти вашу функцию main() . А все программы должны включать в себя эту функцию.
Есть несколько вещей, которые нужно проверить:
- Содержит ли ваш код функцию с именем main ?
- Правильно ли написано имя main ?
- Когда вы компилируете свою программу, видите ли вы, что файл, содержащий функцию main() , компилируется? Если нет, либо переместите функцию main() в другой файл, либо добавьте этот файл в свой проект (для получения дополнительной информации о том, как это сделать, смотрите урок «2.7 – Программы с несколькими файлами кода»).
- Вы точно создали консольный проект? Попробуйте создать новый консольный проект.
Вопрос: Я пытаюсь использовать функциональность C++11/14/17/XX, но она не работает.
Если у вас старый компилятор, он может не поддерживать эти более свежие дополнения к языку. В этом случае обновите свой компилятор.
В случае с современными IDE/компиляторами ваш компилятор может по умолчанию использовать более старый стандарт языка. Мы рассмотрим, как изменить стандарт языка в уроке «0.12 – Настройка компилятора: выбор стандарта языка».
Вопрос: При попытке использовать cin , cout или endl компилятор говорит, что cin , cout или endl являются «необъявленными идентификаторами».
Во-первых, убедитесь, что вы включили следующую строку в верхней части файла:
Во-вторых, убедитесь, что каждое использование cin , cout и end l имеет префикс " std:: ". Например:
Если это не решит вашу проблему, возможно, ваш компилятор устарел или установка повреждена. Попробуйте переустановить и/или обновить компилятор до последней версии.
Вопрос: При попытке использовать endl для завершения напечатанной строки компилятор говорит, что end1 является «необъявленным идентификатором».
Убедитесь, что вы не перепутали букву l (нижний регистр L) в endl с цифрой 1. endl – это все буквы. Убедитесь, что ваш редактор использует шрифт, который проясняет разницу между строчной буквой L, заглавной i и цифрой 1. Кроме того, во многих шрифтах, не предназначенных для программирования, можно легко перепутать заглавную букву o и цифру ноль.
Проблемы с Visual Studio
Вопрос: При компиляции с помощью Microsoft Visual C++ вы получаете фатальную ошибку C1010 с сообщением типа " c:\vcprojects\test.cpp(263) :fatal error C1010: unexpected end of file while looking for precompiled header directive " (неожиданный конец файла при поиске директивы предварительно скомпилированного заголовка).
Эта ошибка возникает, когда компилятор Microsoft Visual C++ настроен на использование предварительно скомпилированных заголовков, но один (или несколько) ваших файлов кода C++ не включает #include "stdafx.h" или #include "pch.h" в качестве первой строки кода файла.
Предлагаемое нами решение – отключить предварительно скомпилированные заголовки, как это сделано в уроке «0.7 – Компиляция вашей первой программы».
Если вы хотите, чтобы предварительно скомпилированные заголовки были включены, чтобы решить эту проблему, просто найдите файл(ы), вызывающий ошибку (в приведенной выше ошибке виновником является test.cpp ), и добавьте следующую строку в самом верху файла):
В более старых версиях Visual Studio используется stdafx.h вместо pch.h , поэтому, если pch.h не решает проблему, попробуйте stdafx.h .
Обратите внимание, что для программ с несколькими файлами каждый файл кода C++ должен начинаться с этой строки.
Кроме того, вы можете отключить предварительно скомпилированные заголовки.
Вопрос: Visual Studio выдает следующую ошибку: " 1MSVCRTD.lib(exe_winmain.obj) : error LNK2019: unresolved external symbol _WinMain@16 referenced in function "int __cdecl invoke_main(void)" (?invoke_main@@YAHXZ) " (неразрешенный внешний символ _WinMain@16 ).
Скорее всего, вы создали не консольное приложение, а графическое приложение Windows. Создайте заново свой проект и убедитесь, что вы создали его как консольный проект Windows (или Win32).
Вопрос: Когда я компилирую свою программу, я получаю предупреждение " Cannot find or open the PDB file " (не могу найти или открыть файл PDB).
Это предупреждение, а не ошибка, поэтому оно не должно повлиять на вашу программу. Однако она раздражает. Чтобы исправить это, перейдите в меню Debug (Отладка) → Options and Settings (Параметры) → Symbols (Символы) и установите флажок Microsoft Symbol Server (Сервер символов Microsoft).
Прочее
Вопрос: У меня есть еще одна проблема, которую я не могу понять. Как я могу быстро получить ответ?
По мере обучения у вас, несомненно, будут возникать вопросы или неожиданные проблемы. Что делать дальше, зависит от вашей проблемы. Но в целом есть несколько вещей, которые вы можете попробовать.
Сначала спросите Google. Найдите хороший способ сформулировать свой вопрос и выполните поиск в Google. Если вы получили сообщение об ошибке, вставьте точное сообщение в Google, используя кавычки. Скорее всего, кто-то уже задавал тот же вопрос, и вы найдете ответ.
Если это не поможет, спросите на сайте вопросов и ответов. Существуют веб-сайты, предназначенные для вопросов и ответов о программировании, например, Stack Overflow. Попробуйте разместить там свой вопрос. Не забудьте подробно описать, в чем заключается ваша проблема, и включить всю необходимую информацию, например, какую ОС и какую IDE вы используете.
Для новичков про stdafx.h
Статья рассчитана на людей, которые знакомятся со средой Visual Studio и пытаются компилировать в ней свои Си++-проекты. В незнакомой среде всё кажется странным и непонятным. Особенно новичков раздражает файл stdafx.h, из-за которого возникают странные ошибки во время компиляции. Очень часто всё заканчивается тем, что новичок долгое время везде старательно отключает Precompiled Headers. Чтобы помочь людям разобраться что к чему, и была написана эта статья.
Для чего нужны Precompiled Headers
Precompiled headers предназначены для ускорения сборки проектов. Обычно программисты начинают знакомиться с Visual C++, используя крошечные проекты. На них сложно заметить выигрыш от precompiled headers. Что с ними, что без них, на глаз программа компилируется одинаковое время. Это добавляет путаницы. Человек не видит для себя пользы от этого механизма и решает, что он для специфичных задач и ему никогда не понадобится. И иногда считает так многие годы.
На самом деле, precompiled headers весьма полезная технология. Пользу от него можно заметить, даже если в проекте всего несколько десятков файлов. Особенно выигрыш становится заметен, если используются такие тяжёлые библиотеки как boost.
Если посмотреть *.cpp файлы в проекте, то можно заметить, что во многие включаются одни и те-же наборы заголовочных файлы. Например, <vector>, <string>, <algorithm>. В свою очередь, эти файлы включают другие заголовочные файлы и так далее.
Всё это приводит к тому, что препроцессор в компиляторе вновь и вновь выполняет идентичную работу. Он должен читать одни и те же файлы, вставлять их друг в друга, выбирать #ifdef ветки и подставлять значения макросов. Происходит колоссальное дублирование одних и тех же операций.
Можно существенно сократить объем работы, которую должен проделать препроцессор при компиляции проекта. Идея в том, чтобы заранее препроцессировать группу файлов и затем просто подставлять готовый фрагмент текста.
На самом деле, делается ещё ряд шагов. Можно хранить не просто текст, а более обработанную информацию. Я не знаю, как именно устроено в Visual C++. Но, например, можно хранить текст уже разбитый на лексемы. Это ещё больше ускорит процесс компиляции.
Как работают Precompiled Headers
Файл, который содержит precompiled headers, имеет расширение «.pch». Имя файла обычно совпадает с названием проекта. Естественно, это и другие используемые имена можно изменить в настройках. Файл может быть весьма большим и зависит от того, как много заголовочных файлов в нём раскрыто. Например, в проекте PVS-Studio он занимает около 3 мегабайт.
Файл *.pch возникает после компиляции stdafx.cpp. Файл собирается с ключом «/Yc». Этот ключ как раз и говорит компилятору, что нужно создать precompiled headers. Файл stdafx.cpp может содержать одну строчку: #include «stdafx.h».
В файле «stdafx.h» находится самое интересное. Сюда нужно включить заголовочные файлы, которые будут заранее препроцессироваться. В качестве примера, вот файл stdafx.h, используемый нами в PVS-Studio (файл сокращён для статьи):
Директивы «#pragma warning» нам нужны, чтобы избавиться от предупреждений, выдаваемых на стандартные библиотеки.
Теперь во все файлы *.c/*.cpp следует включить «stdafx.h». Заодно стоит удалить из этих файлов заголовки, которые уже включаются с помощью «stdafx.h».
- Файл A: <vector>, <string>
- Файл B: <vector>, <algorithm>
- Файл C: <string>, <algorithm>
Достаточно сделать один precompiled header, в котором будут раскрыты <vector>, <string> и <algorithm>. Выигрыш от того, что при препроцессировании не надо читать множество файлов и вставлять их друг друга намного больше, чем потери на синтаксический анализ лишних фрагментов кода.
Как использовать Precompiled Headers
При создании нового проекта Wizard в Visual Studio создаёт два файла: stdafx.h и stdafx.cpp. Именно с помощью них и реализуется механизм precompiled headers.
На самом деле, эти файлы могут называться, как угодно. Важно не название, а параметры компиляции в настройках проекта.
В *.c/*.cpp файле можно использовать только один precompiled header. Однако, в одном проекте может присутствовать несколько разных precompiled headers. Пока будем считать, что он у нас только один.
Итак, если вы воспользовались wizard-ом, то у вас уже есть файлы stdafx.h и stdafx.cpp. Плюс выставлены все необходимые ключи компиляции.
- Во всех конфигурациях для всех *.c/*.cpp файлов включаем использование precompiled headers. Это делается на вкладке «Precompiled Header»:
- Выставляем для параметра «Precompiled Header» значение «Use (/Yu)».
- Для параметра «Precompiled Header File» указываем «stdafx.h».
- Для параметра «Precompiled Header Output File» указываем «$(IntDir)$(TargetName).pch».
Для всех *.c/*.cpp файлов мы указали, что они должны использовать precompiled headers. Этого мало. Теперь в каждый из файлов нужно добавить #include «stdafx.h».
Заголовочный файл «stdafx.h» должен включаться в *.c/*.cpp файл самым первым. Обязательно! Иначе всё равно возникнут ошибки компиляции.
Если подумать, в этом есть логика. Когда файл «stdafx.h» находится в самом начале, то можно подставить уже препроцессированный текст. Этот текст всегда одинаков и ни от чего не зависит.
Представьте ситуацию, если бы мы могли включить до «stdafx.h» ещё какой-то файл. А в этом файле возьмём и напишем: #define bool char. Возникает неоднозначность. Мы меняем содержимое всех файлов, в которых упоминается «bool». Теперь просто так нельзя взять и подставить заранее препроцессированный текст. Ломается весь механизм «precompiled headers». Думаю, это одна из причин, почему «stdafx.h» должен быть расположен в начале. Возможно, есть и другие.
Life hack
Прописывать #include «stdafx.h» во все *.c/*.cpp файлы достаточно утомительно и не интересно. Дополнительно получится ревизия в системе контроля версий, где будет изменено огромное количество файлов. Нехорошо.
Ещё одно неудобство вызывают сторонние библиотеки, включаемые в проект в виде файлов с кодом. Править эти файлы нет смыла. По правильному для них нужно отключить использование «precompiled headers». Однако, если используется несколько мелких сторонних библиотек, это неудобно. Программист постоянно спотыкается об precompiled headers.
Есть вариант, как использовать precompiled headers легко и просто. Способ подойдёт не везде и всегда, но мне он часто помогал.
Можно не прописывать во все файлы #include «stdafx.h», а воспользоваться механизмом «Forced Included File».
Идём на вкладку настроек «Advanced». Выбираем все конфигурации. В поле «Forced Included File» пишем:
Теперь «stdafx.h» автоматически будет включаться в начало ВСЕХ компилируемых файлов. PROFIT!
Больше не потребуется писать #include «stdafx.h» в начале всех *.c/*.cpp файлов. Компилятор сделает это сам.
Что включать в stdafx.h
Это очень важный момент. Бездумное включение в «stdafx.h» всего подряд не только не ускорит компиляцию, но и наоборот замедлит её.
Все файлы, включающие «stdafx.h», зависят от его содержимого. Пусть в «stdafx.h» включен файл «X.h». Если вы поменяете хоть что-то в «X.h», это может повлечь полную перекомпиляцию всего проекта.
Правило. Включайте в «stdafx.h» только те файлы, которые никогда не изменяются или меняются ОЧЕНЬ редко. Хорошими кандидатами являются заголовочные файлы системных и сторонних библиотек.
Если включаете в «stdafx.h» собственные файлы из проекта, соблюдайте двойную бдительность. Включайте только те файлы, которые меняются очень-очень редко.
Если какой-то *.h файл меняется раз в месяц, это уже слишком часто. Как правило, редко удаётся сделать все правки в h-файле с первого раза. Обычно требуется 2-3 итерации. Согласитесь, 2-3 раза полностью перекомпилировать весь проект — занятие неприятное. Плюс полная перекомпиляция потребуется всем вашим коллегам.
Не увлекайтесь с неизменяемыми файлами. Включайте только то, что действительно часто используется. Нет смысла включать <set>, если это нужно только в двух местах. Там, где нужно, там и подключите этот заголовочный файл.
Несколько Precompiled Headers
Зачем в одном проекте может понадобиться несколько precompiled headers? Действительно, это нужно не часто. Но приведу пару примеров.
В проекте используются одновременно *.c и *.cpp файлы. Для них нельзя использовать единый *.pch файл. Компилятор выдаст ошибку.
Нужно создать два *.pch файла. Один должен получаться при компилировании C-файла (xx.c), а другой при компилировании C++-файла (yy.cpp). Соответственно, в настройках надо указать, чтобы в С-файлах использовался один precompiled header, а в С++-файлах — другой.
Примечание. Не забудьте указать разные имена для *.pch файлов. Иначе один файл будет перетирать другой.
Другая ситуация. Одна часть проекта использует одну большую библиотеку, а другая часть другую большую библиотеку.
Естественно, не стоит всем участкам кода знать про обе библиотеки. В (неудачных) библиотеках могут пересекаться имена каких-то сущностей.
Логично сделать два precompiled headers и использовать их в разных участках программы. Как уже отмечалось, можно задать произвольные имена файлов, из которых генерируются *.pch файлы. Да и имя *.pch файла тоже можно изменить. Всё это, конечно, требуется делать аккуратно, но ничего сложного в использовании двух precompiled headers нет.
Типовые ошибки при использовании Precompiled Headers
Прочитав внимательно материал выше, вы сможете понять и устранить ошибки, связанные с stdafx.h. Но давайте ещё раз пройдёмся по типовым ошибкам компиляции и разберём их причины. Повторенье — мать ученья.
Fatal error C1083: Cannot open precompiled header file: ‘Debug\project.pch’: No such file or directory
- Файл stdafx.cpp не компилировался и, как следствие, *.pch файл ещё не создан. Такое может быть, если, например, в начале очистить проект (Clean Solution), а потом попробовать скомпилировать один *.cpp файл (Compile Ctrl-F7). Решение: скомпилируйте проект целиком или как минимум файл stdafx.cpp.
- В настройках ни указано ни одного файла, из которого должен генерироваться *.pch файл. Речь идёт о ключе компиляции /Yc. Как правило, такая ситуация возникает у начинающих, которые захотели использовать precompiled headers для своего проекта. Как это сделать описано выше в разделе «Как использовать Precompiled Headers».
Fatal error C1010: unexpected end of file while looking for precompiled header. Did you forget to add ‘#include «stdafx.h»’ to your source?
Сообщение говорит само за себя, если его прочитать. Файл компилируется с ключом /Yu. Это значит, что следует использовать precompiled header. Но в файл не включён «stdafx.h».
Нужно вписать в файл #include «stdafx.h».
Если это невозможно, то следует не использовать precompiled header для этого *.c/*.cpp файла. Уберите ключ /Yu.
Fatal error C1853: ‘project.pch’ precompiled header file is from a previous version of the compiler, or the precompiled header is C++ and you are using it from C (or vice versa)
В проекте присутствуют как C (*.c), так и C++ (*.cpp) файлы. Для них нельзя использовать единый precompiled header (*.pch файл).
- Отключить для всех Си-файлов использование precompiled headers. Как показывает практика, *.с файлы препроцессируются в несколько раз быстрее, чем *.cpp файлы. Если *.c файлов не очень много, то, отключив precompiled headers для них, вы ничего не потеряете
- Завести два precompiled headers. Первый должен создаваться из stdafx_cpp.cpp, stdafx_cpp.h. Второй из stdafx_c.c, stdafx_c.h. Соответственно, в *.c и *.cpp файлах следует использовать разные precompiled headers. Имена *.pch файлов естественно тоже должны различаться.
Из-за precompiled header компилятор глючит
Скорее всего, что-то сделано не так. Например, #include «stdafx.h» расположен не в самом начале.
Этот код не скомпилируется. Компилятор выдаст на первый взгляд странное сообщение об ошибке:
Компилятор считает, что все, что указано до строчки #include «stdafx.h» (включительно), является precompiled header. При компиляции файла компилятор заменит все, что до #include «stdafx.h» на текст из *.pch файла. В результате теряется строчка «int A = 10».
Содержимое файла «my.h» не будет использоваться. В результате, нельзя будет использовать функции, объявленные в этом файле. Такое поведение очень сбивает программистов с толку. Они «лечат» его полным отключением precompiled headers и потом рассказывают байки о глючности Visual C++. Запомните, компилятор — это один из наиболее редко глючащих инструментов. В 99.99% случаев надо не злиться на компилятор, а искать ошибку у себя (Proof).
Чтобы таких ситуаций не было, ВСЕГДА пишите #include «stdafx.h» в самом начале файла. Комментарии перед #include «stdafx.h» можно оставить. Они всё равно никак не участвуют в компиляции.
Ещё один вариант — используйте Forced Included File. См. выше раздел «Life hack».
Из-за precompiled headers проект постоянно перекомпилируется целиком
В stdafx.h включён файл, который регулярно редактируется. Или случайно включён автогенерируемый файл.
Внимательно проверьте содержимое файла «stdafx.h». В него должны входить только заголовочные файлы, которые не изменяются или изменяются крайне редко. Учтите, что включённые файлы могут не меняться, но внутри они ссылаются на другие изменяющиеся *.h файлы.
Творится что-то непонятное
Иногда может возникнуть ситуация, что вы поправили код, а ошибка не исчезает. Отладчик показывает непонятные вещи.
Причиной может быть *.pch файл. Как-то так получилось, что компилятор не замечает изменения в одном из заголовочных файлов и не перестраивает *.pch файл. В результате, подставляется старый код. Возможно, это происходило из-за каких-то сбоев, связанных с временем модификации файлов.
Это ОЧЕНЬ редкая ситуация. Но она возможна и про неё надо знать. Я за многие годы программирования сталкивался с ней только 2-3 раза. Помогает полная перекомпиляция проекта.
Проект, использующий precompiled headers не удаётся проверить с помощью PVS-Studio
Это наиболее частая ситуация, с которой к нам обращаются в поддержку. Подробности изложены в документации: «Устранение неисправностей при работе PVS-Studio». Здесь опишу ситуацию кратко.
Если решение (solution) компилируется, это вовсе не значит, что оно правильно устроено. Часто одно решение (solution) содержит множество проектов. В каждом проекте используются свои precompiled headers (имеется свой stdafx.h и stdafx.cpp).
Возникают проблемы, когда начинают использовать файлы из соседнего проекта. Это удобно и так часто делается. Вот только забывают, что в *.cpp файле написано: #include «stdafx.h».
И, какой из stdafx.h подхватится, это интересный вопрос. Но раз программа компилируется — программисту везёт.
К сожалению, нам сложно повторить поведение, которое возникает при использовании *.pch файла. «Честный» препроцессор работает по-другому.
В том, что solution, на самом деле, устроен не верно, можно убедиться, временно отключив precompiled headers. Сразу может вылезти масса интересных ошибок, и программист будет искренне удивляться, каким же чудом компилировался его проект.
За подробностями вновь делаю отсылку к документации. Плюс, если что-то всё равно не ясно, мы подскажем в поддержке.
Заключение
Как вы увидели, ничего сложного в precompiled headers нет. Все «многочисленные глюки компилятора», с которыми сталкивается программист при их использовании, на самом деле, являются непониманием принципов работы. Надеюсь, эта статья поможет устранить непонимание.
Precompiled headers являются очень полезным механизмом, позволяющим существенно увеличить скорость компиляции проектов.
Error C1083: Cannot open include file: 'stdafx.h'
When I compiled this program (from C++ Programming Language 4th edition):
It gave me these errors:

I run it on Microsoft Visual Studio 2013, on Windows 7. How to fix it?
6 Answers 6
You have to properly understand what is a «stdafx.h», aka precompiled header. Other questions or Wikipedia will answer that. In many cases a precompiled header can be avoided, especially if your project is small and with few dependencies. In your case, as you probably started from a template project, it was used to include Windows.h only for the _TCHAR macro.
Then, precompiled header is usually a per-project file in Visual Studio world, so:
- Ensure you have the file «stdafx.h» in your project. If you don’t (e.g. you removed it) just create a new temporary project and copy the default one from there;
- Change the #include <stdafx.h> to #include «stdafx.h» . It is supposed to be a project local file, not to be resolved in include directories.
Secondly: it’s inadvisable to include the precompiled header in your own headers, to not clutter namespace of other source that can use your code as a library, so completely remove its inclusion in vector.h .