Разное

Include stdafx h что это: c++ — Где взять stdafx.h в Visual Studio 2019?

Содержание

Неустранимая ошибка C1083 | Microsoft Learn

  • Статья
  • Чтение занимает 6 мин

Не удается открыть файл filetype : «file«: message

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

Указано неверное имя файла

При вводе имени файла допущена ошибка. Например, примененная к объекту директива

#include <algorithm.h>

может не найти файл, который вы хотели. Большинство файлов заголовков стандартной библиотеки C++ не имеют расширения H-файла. Заголовок <алгоритма> не найден этой #include директивой. Чтобы устранить эту проблему, убедитесь, что введено правильное имя файла, как в следующем примере:

#include <algorithm>

Некоторые заголовки библиотеки времени выполнения C расположены в подкаталоге стандартного каталога включения. Например, чтобы включить sys/types.h, необходимо включить sys имя подкаталога в директиву #include :

#include <sys/types.h>

Файл не включен в путь поиска включения

Компилятору не удается найти файл, используя правила поиска, которые указаны в директиве #include или #import. Например, если имя файла заголовка заключено в кавычки,

#include "myincludefile. h"

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

Если имя заключено в угловые скобки,

#include <stdio.h>

компилятор следует пути поиска, определяемого средой сборки, /I параметром компилятора, /X параметром компилятора и переменной среды INCLUDE . Дополнительные сведения, включая конкретные сведения о порядке поиска, используемом для поиска файла, см. в директиве #include (C/C++) и директиве #import.

Если файлы включения находятся в другом каталоге относительно исходного каталога и используете относительный путь в директивах include, следует использовать двойные кавычки вместо угловых скобок. Например, если файл myheader.h заголовка находится в подкаталоге источников проекта с именами заголовков, в этом примере не удается найти файл и вызвать C1083:

#include <headers\myheader.h>

но этот пример работает:

#include "headers\myheader.h"

Относительные пути также можно использовать с каталогами в пути поиска включения. Если вы добавляете каталог в переменную среды INCLUDE или в путь include directories в Visual Studio, не добавляйте часть пути к директивам include. Например, если заголовок находится по адресу \path\example\headers\myheader.hи добавляется \path\example\headers\ в путь включения каталогов в Visual Studio, но директива #include ссылается на файл как

#include <headers\myheader.h>

затем файл не найден. Используйте правильный путь относительно каталога, указанного в пути поиска include. В этом примере можно изменить путь \path\example\поиска включения или удалить headers\ сегмент пути из директивы #include .

Проблемы со сторонними библиотеками и vcpkg

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

Файл находится в проекте, но не включает путь поиска

Даже если файлы заголовков перечислены в Обозреватель решений как часть проекта, файлы обнаруживаются компилятором только в том случае, если они ссылаются #include на исходный файл или #import директиву и находятся в пути поиска включаемых файлов. Для различных типов построений могут использоваться разные пути поиска. Параметр /X компилятора можно использовать для исключения каталогов из пути поиска включения. Это позволяет использовать для разных построений разные файлы include, которые имеют одно имя, но расположены в разных каталогах. Таким образом создается альтернатива условной компиляции с помощью команд препроцессора. Дополнительные сведения о параметре /X компилятора см. в разделе /X (Пропуск стандартных путей включения).

Чтобы устранить эту проблему, исправьте путь, используемый компилятором для поиска включаемого или импортируемого файла. Новый проект использует пути поиска по умолчанию. Возможно, потребуется изменить путь поиска включения, чтобы добавить каталог для проекта. При компиляции в командной строке добавьте путь к переменной среды INCLUDE или /I параметр компилятора, чтобы указать путь к файлу.

Чтобы задать путь к каталогу include в Visual Studio, откройте диалоговое окно страниц свойств проекта. Выберите каталоги VC++ в разделе «Свойства конфигурации » в левой области, а затем измените свойство Include Directoryies . Дополнительные сведения о каталогах для отдельных пользователей и проектов, искомых компилятором в Visual Studio, см. на странице свойств каталогов VC++. Дополнительные сведения о параметре /I компилятора см. в разделе /I (Дополнительные каталоги включения).

Среда INCLUDE или LIB командной строки не задана

Если компилятор вызывается из командной строки, для указания путей поиска часто используются переменные среды. Если путь поиска, описанный переменной среды INCLUDE или LIB , неправильно задан, может возникнуть ошибка C1083. Настоятельно рекомендуется использовать ярлык командной строки разработчика, чтобы задать базовую среду для сборок командной строки. Дополнительные сведения см. в разделе «Сборка C/C++ в командной строке». Дополнительные сведения об использовании переменных среды см. в разделе «Практическое руководство. Использование переменных среды в сборке».

Файл может быть заблокирован или использоваться

Если вы используете другую программу для редактирования или доступа к файлу, возможно, файл заблокирован. Попробуйте закрыть файл в другой программе. Иногда другая программа может быть самой Visual Studio, если вы используете параметры параллельной компиляции. Если параметр параллельной сборки отключает ошибку, это проблема. Эта проблема также может быть связана с другими параллельными системами сборки. Будьте внимательны, чтобы задать зависимости файлов и проектов, чтобы порядок сборки был правильным. В некоторых случаях рассмотрите возможность создания промежуточного проекта для принудительного порядка сборки зависимостей для общего файла, который может быть создан несколькими проектами. Иногда антивирусные программы временно блокируют недавно измененные файлы для сканирования. По возможности рекомендуется исключить каталоги сборки проекта из антивирусного сканера.

Включена неправильная версия имени файла

Ошибка C1083 также может указывать на включение неверной версии файла. Например, построение может включать неверную версию файла, содержащего директиву #include для файла заголовка, который не предназначен для данного построения. Например, некоторые файлы могут применяться только к сборкам x86 или к отладочным сборкам. Если файл заголовка не найден, компилятор выдает ошибку C1083. Для исправления этой проблемы необходимо использовать правильный файл, а не добавлять в построение файл заголовка или каталог.

Если проект настроен на использование предварительно скомпилированных заголовков, необходимо создать соответствующие .pch файлы, чтобы можно было скомпилировать файлы, использующие содержимое заголовка. Например, pch.cpp файл (stdafx.cpp в Visual Studio 2017 и более ранних версиях) автоматически создается в каталоге проекта для новых проектов. Сначала необходимо скомпилировать этот файл, чтобы создать предкомпилированные файлы заголовков. В стандартной структуре процесса сборки это делается автоматически. Дополнительные сведения см. в разделе «Создание предварительно скомпилированных файлов заголовков».

Дополнительные причины

  • Вы установили пакет SDK или стороннюю библиотеку, но не открывали новое окно командной строки разработчика после установки пакета SDK или библиотеки. Если пакет SDK или библиотека добавляет файлы в путь

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

  • Файл использует управляемый код, но параметр /clr компилятора не указан. Дополнительные сведения см. в разделе /clr (компиляция среды CLR).

  • Файл компилируется с помощью другого /analyze параметра параметра компилятора, отличного от используемого для предварительной компиляции заголовков. При предварительной компиляции заголовков проекта все должны использовать одни и те же /analyze параметры. Дополнительные сведения см. в разделе

    /analyze (Анализ кода).

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

  • Файл, каталог или диск доступен только для чтения.

  • Visual Studio или программы командной строки не имеют достаточных разрешений для чтения файла или каталога. Это может произойти, например, если файлы проекта имеют другое право собственности, чем процесс, выполняемый в Visual Studio или программы командной строки. Иногда эту проблему можно устранить, запустив Visual Studio или командную строку разработчика от имени администратора.

  • Недостаточно дескрипторов файлов. Закройте часть приложений и повторите компиляцию. Эта ситуация маловероятна в обычных условиях. Однако она может возникать при построении крупных проектов на компьютере с ограниченной физической памятью.

Пример

В следующем примере возникает ошибка C1083, если файл "test.h" заголовка не существует в исходном каталоге или в пути поиска включения.

// C1083.cpp
// compile with: /c
#include "test.h"   // C1083 test.h does not exist
#include "stdio.h"  // OK

Сведения о сборке проектов C/C++ в интегрированной среде разработки или командной строке, а также о настройке переменных среды см. в разделе «Проекты» и «Системы сборки».

См. также раздел

  • Свойства MSBuild

Precompiled Headers Explained

Следующее Предыдущее Главная страница

Почти все разработчики, использующие Visual C++, сталкиваются с файлом stdafx.h, в который можно положить много-много различных директив препроцессора. И так мало понимают, зачем это нужно и как с этим работать…

Precompiled Header

Вы, наверное, слышали о понятии Precompiled Header. Precompiled Header

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

Рассмотрим программу Hello World:

#include <tchar.h>
#include <iostream>
int _tmain(int argc, _TCHAR* argv[]) {
    std::cout << "Hello World!" << std::endl;
    return 0;
}

А теперь внимание: после обработки этого файла прекомпилятором, его размер возрастает до 996 килобайт! Я повторюсь: 996 килобайт, из которых 854 составляют полезный код (остальное — комментарии), а размер рабочего кода программы — аж 142 байта. Похоже, для компиляции нашего простейшего cpp-файла компилятору прийдется изрядно потрудиться. Причем над каждым cpp-файлом проекта.

Естественно, лучше предварительно обработать неизменящиеся куски кода, превратив их в удобный и быстрый формат для последующей обработки в составе исходного кода приложения. Компиляторы Visual C++ и GCC поддерживают такую обработку и она носит имя

Precompiled Header.

Использование Precompiled Header в Visual C++

Мастер создания проекта Visual C++ предлагает свои услуги по настройке Precompiled Header. В простейшем случае, среда дает разработчику возможность выбора — использовать этот механизм или нет. В большинстве случаев использование Precompiled Header настраивается автоматически.

Анализ настроек Precompiled Header мастеров Visual C++

Что же мы получаем при автоматической настройке Precompiled Header средой разработки Visual Studio?

  1. Заголовочный файл stdafx.h

    В этом файле содержатся, как правило, только директивы препроцессора, подключающие внешние заголовочные файлы.

  2. cpp-файл stdafx.cpp

    Состоит из единственной директивы #include "stdafx.h" и используется для генерации Precompiled Header. Следующая картинка демонстрирует свойства файла stdafx.cpp, раздел C/C++, подраздел Precompiled Headers:

  3. Каждый cpp-файл проекта, использующий Precompiled Header, обязан включать этот заголовочный файл соответствующей директивой #include "stdafx.h"

    При этом компилятор игнорирует любой текст до момента включения

    stdafx. h! А в случае его отсутствия — выдает ошибку fatal error C1010: unexpected end of file while looking for precompiled header. Did you forget to add ‘#include «stdafx.h»‘ to your source?

  4. Использование Precompiled Header установлено на уровне cpp-файлов всего проекта, как показано на картинке:

Настройка Precompiled Header вручную

Опираясь на вышенаписанное, последовательность действий простая:

  1. Создать файл CommonIncludes.h
  2. Создать файл CommonIncludes.cpp и добавить туда одну строчку — #include "CommonIncludes.h"
  3. Поменять нужные настройки Precompiled Headers в свойствах файла CommonIncludes.cpp
  4. Поменять настройки Precompiled Headers на уровне проекта или на уровне отдельных cpp-файлов
  5. Добавить #include "CommonIncludes.h" в начало соответствующих cpp-файлов исходного кода

Продвинутое использование Precompiled Header

Как правило, в stdafx. h, созданный визардом, лепят все, что можно влепить. В результате в каждый cpp-файл включается совершенно ненужный ему контент! Поэтому, логично включать в stdafx.h только наиболее используемые заголовочные файлы.

Директивы прекомпилятора в stdafx.h распостраняются одинаковым образом на все cpp-файлы, включающие данный заголовочный файл. Бывает, необходимо настроить поведение библиотеки (в рамках отдельного cpp-файла или группы таких файлов) путем определения каких-то символов перед включением соответствующего заголовочного файла. Первое, что приходит на ум, — определить эти символы в cpp-файле и еще раз включить заголовочный файо библиотеки. Но, нет, я же писал, что компилятор игнорирует любой исходный код до строчки

#include "stdafx.h"! Соответственно, повторное включение заголовочных файлов будет просто проигнорировано. Получается, нужно удалять включения заголовочных файлов библиотек из stdafx.h и добавлять их в каждый отдельный cpp-файл.

Также, проект не ограничен одним Precompiled Header! Вполне можно содзать пару файлов Subsystem1Includes.h, Subsystem1Includes.cpp, отвечающих за отдельный Precompiled Header в рамках некоторой группы файлов исходного кода.

Компилятор Visual C++ имеет ограничение на размер pch-файла. На практике это выглядит следующим образом:

error C3859: virtual memory range for PCH exceeded; please recompile with a command line option of '-Zm130' or greater
fatal error C1076: compiler limit : internal heap limit reached; use /Zm to specify a higher limit

В таком случае спасет опция компилятора /Zm:

Использование заголовка «stdafx.h» в C++ с примерами

Файл заголовка содержит набор предопределенных функций стандартной библиотеки. Заголовочный файл может быть включен в программу с помощью директивы предварительной обработки C «#include» . Все заголовочные файлы имеют расширение « .h» .

Синтаксис:

 #include  / "header_file" 

Здесь, 
#: Директива препроцессора
header_file: Имя файла заголовка 0007

#include указывает компилятору добавить header_file в исходный код перед выполнением операторов программы.

Заголовочный файл «stdafx.h»

Этот заголовочный файл является предварительно скомпилированным заголовочным файлом. Основная цель этого заголовочного файла — сократить время компиляции. Этот заголовочный файл обычно используется в Microsoft Visual Studio.

Без заголовочного файла stdafx.h:

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

C ++

#include

#include

Использование Namesspace ;

 

int main()

{

     cout << 900!" ;

     возврат 0;

}

Выход

 GFG! 

С заголовочным файлом stdafx. h:

«stdafx.h» пригодится, когда мы хотим компилировать программу снова и снова. Он должен быть включен в начало всех файлов заголовков, и теперь при первой компиляции программы скомпилированная версия всех файлов заголовков, присутствующих в программе, будет сохранена в файле «stdafx.h». Теперь каждый раз, когда программа компилируется, компилятор берет скомпилированную версию файлов заголовков из файла «stdafx.h», а не компилирует одни и те же файлы заголовков с нуля снова и снова.

Пример:

В эту программу включен заголовочный файл «stdafx.h». Теперь, когда программа скомпилирована, cmath и iostream будут скомпилированы с нуля, а скомпилированная версия cmath и iostream будет сохранена в файле «stadafx.h». Для следующей компиляции компилятор автоматически выбирает скомпилированную версию этих заголовочных файлов из заголовочного файла «stadafx».

C++

 

#include "stdafx. h"

 

#include

#include

 

использование пробела

9004;

 

int main()

{

     cout << 900!" ;

     возврат 0;

}

Вывод:

 prog.cpp:5:20: фатальная ошибка: stdafx.h: нет такого файла или каталога
компиляция прекращена. 

Преимущества заголовочного файла stdafx.h:

  • Сокращает время компиляции тех программ, которые требуется компилировать снова и снова.
  • Сокращает ненужную обработку.

StdAfx.h | Как не писать код

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


Назначение предварительно скомпилированных заголовков

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

Предварительно скомпилированные заголовки на самом деле очень полезная технология. Выгоду можно увидеть даже с проектом всего из нескольких десятков файлов. Использование таких тяжелых библиотек в качестве буста сделает прирост производительности особенно заметным.

Если вы изучите файлы *.cpp в своем проекте, то заметите, что многие из них содержат одни и те же наборы заголовков, например , , . Эти заголовки, в свою очередь, включают в себя другие заголовки и так далее.

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

Объем работы препроцессора во время компиляции проекта может быть значительно уменьшен. Идея состоит в том, чтобы предварительно обработать группу файлов, а затем просто вставить уже подготовленные текстовые фрагменты, где это необходимо.

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

Как работают предварительно скомпилированные заголовки

Файл, содержащий предварительно скомпилированные заголовки, имеет расширение «.pch». Имя файла обычно совпадает с названием проекта, но вы, естественно, можете изменить это и любые другие используемые имена в настройках. Файл *.pch может быть довольно большим, что зависит от того, сколько заголовков в нем развернуто.

В PVS-Studio, например, он занимает около 3 Мбайт.

Файл *.pch создается в результате компиляции файла stdafx.cpp. Этот файл создается с переключателем «/Yc», который используется специально для указания компилятору создавать предварительно скомпилированные заголовки. Файл stdafx.cpp может содержать одну строку: #include «stdafx.h».

Самое интересное хранится в файле «stdafx.h». В него должны быть включены все заголовочные файлы, которые необходимо предварительно скомпилировать. Например, ниже показан файл stdafx.h, который мы используем в PVS-Studio (текст сокращен для статьи):

 #include "VivaCore/VivaPortSupport.h"
//Для /Стены
#предупреждение прагмы (push)
# предупреждение прагмы (отключить: 4820)
# предупреждение прагмы (отключить: 4619)
# предупреждение прагмы (отключить: 4548)
# предупреждение прагмы (отключить: 4668)
# предупреждение прагмы (отключить: 4365)
# предупреждение прагмы (отключить: 4710)
# предупреждение прагмы (отключить: 4371)
# предупреждение прагмы (отключить: 4826)
# предупреждение прагмы (отключить: 4061)
# предупреждение прагмы (отключить: 4640)
#include  h>
#include <строка>
#include <вектор>
#include <иопоток>
#include 
#include <алгоритм>
#include <набор>
#include <карта>
#include <список>
#include <дек>
#include <память>
#pragma warning(pop) //Для /Wall 

Директивы «#pragma warning» необходимы для избавления от предупреждений, генерируемых стандартными библиотеками.

Теперь файл «stdafx.h» должен быть включен во все файлы *.c/*.cpp. Вы также должны удалить из этих файлов все заголовки, уже включенные в «stdafx.h».

Но что делать, если в разных файлах используются несколько похожие, но все же разные наборы заголовков? Например:

  • Файл A: <вектор>, <строка>
  • Файл B: <вектор>, <алгоритм>
  • Файл C: <строка>, <алгоритм>

Следует ли создавать отдельные предварительно скомпилированные заголовки? Ну, вы можете сделать это, но вам не нужно.

Вам нужно создать только один предварительно скомпилированный заголовок, в котором будут развернуты <вектор>, <строка> и <алгоритм>. Выгода от того, что препроцессору не нужно читать ряд файлов и вставлять их друг в друга, перевешивает потери на синтаксическом анализе дополнительных фрагментов кода.

Как использовать предварительно скомпилированные заголовки

При запуске нового проекта мастер Visual Studio создает два файла: stdafx.h и stdafx.cpp. Именно через них реализуется механизм предкомпилированных заголовков.

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

Файл *.c/*.cpp может использовать только один предварительно скомпилированный заголовок. Однако один проект может содержать несколько разных предварительно скомпилированных заголовков. Предположим, что у нас есть только один на данный момент.

Таким образом, если вы воспользовались Мастером, файлы stdafx.h и stdafx.cpp уже созданы для вас, а также определены все необходимые параметры компиляции.

Если вы не использовали в своем проекте опцию предварительно скомпилированных заголовков, давайте узнаем, как ее включить. Предлагаю следующий алгоритм:

  1. Включить предварительно скомпилированные заголовки во всех конфигурациях для всех файлов *.cpp. Это можно сделать на вкладке «Предварительно скомпилированный заголовок»:
    1. Установите значение «Использовать (/Yu)» для параметра «Предварительно скомпилированный заголовок».
    2. Установите «stdafx.h» для параметра «Предварительно скомпилированный файл заголовка».
    3. Установите «$(IntDir)$(TargetName).pch» для параметра «Выходной файл предварительно скомпилированного заголовка».
  2. Создайте файл stdafx.h и добавьте его в проект. Мы включим в этот файл те заголовки, которые мы хотим предварительно обработать.
  3. Создайте файл stdafx.cpp и добавьте его в проект. В этом файле всего одна строка: #include «stdafx.h».
  4. Изменить настройки файла stdafx.cpp во всех конфигурациях; установите значение «Создать (/ Yc)» для параметра «Предварительно скомпилированный заголовок».

Теперь мы включили опцию предварительно скомпилированных заголовков. Если мы запустим компиляцию сейчас, компилятор создаст файл *.pch. Однако компиляция завершится чуть позже из-за ошибок.

Мы настроили все файлы *.c/*.cpp на использование предварительно скомпилированных заголовков, но это только начало. Теперь нам нужно добавить #include «stdafx.h» в каждый файл.

Заголовок «stdafx.h» должен быть самым первым для включения в файл *.c/*.cpp. Это обязательно! В противном случае вы гарантированно получите ошибки компиляции.

В этом действительно есть смысл, если подумать. Когда файл «stdafx.h» включен в самом начале, вы можете подставить в файл уже предварительно обработанный текст. Этот текст остается неизменным все время и ни на что не влияет.

А теперь представьте, что мы подключили какой-то другой файл до «stdafx.h», и этот файл содержит строку #define bool char. Это сделает ситуацию неопределенной, так как мы изменили содержимое всех файлов, где упоминается «bool». Теперь вы не можете просто вставить предварительно обработанный текст, так как весь механизм «прекомпилированных заголовков» ломается. Я считаю, что это одна из причин, почему «stdafx.h» должен быть включен в первую очередь. Возможно, есть и какие-то другие причины.

Лайфхак

Вводить вручную #include «stdafx.h» во все файлы *.c/*.cpp довольно утомительно и скучно. Кроме того, вы получите новую ревизию в системе контроля версий с большим количеством измененных файлов. Это нехорошо.

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

Однако есть более простой способ обработки предварительно скомпилированных заголовков. Этот метод не является универсальным, но во многих случаях он мне помогал.

Вместо того, чтобы вручную добавлять #include «stdafx.h» во все файлы, вы можете использовать опцию «Forced Included File».

Перейдите на вкладку «Дополнительно». Выберите все конфигурации. В поле «Forced Included File» напишите следующий текст:

StdAfx.h;%(ForcedIncludeFiles)

С этого момента «stdafx.h» будет автоматически включаться в начало ВСЕХ компилируемых файлов. ВЫГОДА!

Вам больше не нужно вручную добавлять #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 раза довольно неприятно, не так ли? Кроме того, все ваши коллеги должны будут сделать то же самое.

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

Несколько предкомпилированных заголовков

Для чего может понадобиться несколько прекомпилированных заголовков в одном проекте? Ну, это действительно довольно редкая ситуация. Но вот пара примеров.

Представьте, что в проекте одновременно используются файлы *.c и *.cpp. Использовать для них общий файл *.pch нельзя — компилятор выдаст ошибку.

Необходимо создать два файла *.pch. Один из них создается после компиляции C-файла (xx.c), другой — после компиляции C++-файла (yy.cpp). Соответственно, вы должны указать в настройках использовать один прекомпилированный заголовок для C-файлов, а другой для C++-файлов.

Примечание. Не забудьте задать разные имена для этих двух файлов *.pch. В противном случае они будут заменять друг друга.

Другая ситуация:
Одна часть проекта использует одну большую библиотеку, а другая часть использует другую большую библиотеку.

Естественно, разные части проекта не должны знать об обеих библиотеках: возможно (к несчастью) совпадение имен сущностей в разных библиотеках.

Логично создать два предварительно скомпилированных заголовка и использовать их в разных частях программы. Как мы уже упоминали, вы можете использовать любые имена для файлов, из которых создаются файлы *. pch. Ну и даже имя файла *.pch тоже можно поменять. Конечно, все это нужно делать очень аккуратно, но ничего особо сложного в использовании двух предварительно скомпилированных заголовков нет.

Типичные ошибки при использовании предварительно скомпилированных заголовков

Теперь, когда вы внимательно прочитали текст выше, вы поймете и устраните все ошибки, связанные с stdafx.h. Но предлагаю еще раз быстро просмотреть типичные ошибки начинающих программистов и разобраться в их причинах. Практика делает совершенным.

Неустранимая ошибка C1083: Не удается открыть файл предварительно скомпилированного заголовка: «Debug\project.pch»: Нет такого файла или каталога

Вы пытаетесь скомпилировать файл, который использует предварительно скомпилированный заголовок, а соответствующий файл *.pch отсутствует. Возможные причины:

  1. Файл stdafx.cpp не был скомпилирован, поэтому файл *.pch еще не создан. Это может произойти, например, когда вы сначала очищаете решение, а затем пытаетесь скомпилировать один файл *. cpp (Компилировать Ctrl-F7). Чтобы решить проблему, скомпилируйте все решение или хотя бы файл stdafx.cpp.
  2. В настройках не указан файл для генерации файла *.pch - то есть проблемы с ключом компиляции /Yc. Эта проблема характерна для новичков в Visual Studio, которые впервые пытаются использовать предварительно скомпилированные заголовки в своем проекте. Чтобы узнать, как это сделать правильно, см. выше раздел «Как использовать предварительно скомпилированные заголовки».

Неустранимая ошибка C1010: неожиданный конец файла при поиске предварительно скомпилированного заголовка. Вы забыли добавить «#include «stdafx.h»» в свой исходный код?

Текст ошибки говорит сам за себя, если вы его прочтете. Файл компилируется с ключом /Yu. Это означает, что должен использоваться предварительно скомпилированный заголовок, но в файле отсутствует «stdafx.h».

В файл необходимо добавить #include «stdafx.h».

Если вы не можете этого сделать, не используйте предварительно скомпилированный заголовок для этого файла *. c/*.cpp. Удалите ключ /Ю.

Неустранимая ошибка C1853: предварительно скомпилированный заголовочный файл 'project.pch' взят из предыдущей версии компилятора, или предварительно скомпилированный заголовок - это C++, и вы используете его из C (или наоборот)

Проект содержит оба C (* .c) и C++ (*.cpp). Вы не можете использовать для них общий предварительно скомпилированный заголовок (файл *.pch).

Возможные решения:

  1. Отключить предварительно скомпилированные заголовки для всех C-файлов. Практика показывает, что файлы *.c препроцессируются в несколько раз быстрее, чем файлы *.cpp. Если у вас всего несколько файлов *.c, вы не потеряете в производительности, отключив для них предварительно скомпилированные заголовки.
  2. Создайте два предварительно скомпилированных заголовка. Первый должен быть сгенерирован из stdafx_cpp.cpp, stdafx_cpp.h; второй из stdafx_c.c, stdafx_c.h. Соответственно, вы должны использовать разные предварительно скомпилированные заголовки для файлов *. c и *.cpp. Имена файлов *.pch, разумеется, тоже должны быть разными.

Компилятор неправильно себя ведет при использовании предварительно скомпилированных заголовков

Должно быть, вы сделали что-то не так. Например, строка #include «stdafx.h» не первая в файле.

Взгляните на этот пример:

 int A = 10;
#include "stdafx.h"
int _tmain (int argc, _TCHAR * argv []) {
  вернуть А;
} 

Этот код не скомпилируется, компилятор выдает на первый взгляд странное сообщение об ошибке:

 error C2065: 'A' : необъявленный идентификатор 

Он считает, что весь текст до #include «stdafx.h» (включая эту строку) является предварительно скомпилированным заголовком. При компиляции файла компилятор заменит текст перед #include «stdafx.h» на текст из файла *.pch. Это приведет к потере строки «int A = 10».

Правильный код должен выглядеть так:

 #include "stdafx.h"
интервал А = 10;
int _tmain (int argc, _TCHAR * argv []) {
  вернуть А;
} 

Еще один пример:

 #include "my. h"
#include "stdafx.h" 

Содержимое файла "my.h" использоваться не будет. В результате вы не сможете использовать функции, объявленные в этом файле. Такое поведение сильно смущает программистов. Они пытаются «вылечить» его, полностью отключив предварительно скомпилированные заголовки, а потом придумывают истории о том, насколько глючен Visual C++. Помните одну вещь: компилятор — это один из инструментов с наименьшим количеством ошибок. В 9В 9,99% случаев злиться надо не на компилятор, а на ошибки в собственном коде (Proof).

Чтобы избежать подобных неприятностей, ПОСТОЯННО добавляйте #include «stdafx.h» в самое начало файла. Ну, вы можете оставлять комментарии перед #include «stdafx.h»; они в любом случае не участвуют в компиляции.

Другой способ — использовать Forced Included File. Смотрите раздел «Лайфхак» выше.

Весь проект полностью перекомпилируется при использовании предварительно скомпилированных заголовков

Вы добавили в stdafx.h файл, который постоянно редактируете. Или вы могли включить автоматически сгенерированный файл по ошибке.

Внимательно изучите содержимое файла «stdafx.h»: он должен содержать только заголовки, которые никогда или очень редко изменяются. Имейте в виду, что хотя некоторые включаемые файлы не изменяются сами по себе, они могут содержать ссылки на другие файлы *.h, которые изменяются.

Происходит что-то странное

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

Эта проблема может быть связана с файлом *.pch. Компилятор почему-то не замечает, что один из заголовочных файлов изменился, поэтому не перекомпилирует файл *.pch, а продолжает вставлять ранее сгенерированный текст. Это могло быть вызвано некоторыми ошибками, связанными со временем модификации файла.

Это ЧРЕЗВЫЧАЙНО редкая ситуация. Но это возможно, и вы должны знать об этом. Лично я сталкивался с этой проблемой всего 2 или 3 раза за многолетнюю карьеру.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *