Общая ошибка компилятора что делать
Распространенные ошибки компилятора
В этом разделе показаны типичные ошибки компилятора, возникающие при переносе существующей базы кода. Эти примеры происходят из кода HAL на уровне системы, хотя эти понятия напрямую применимы к коду уровня пользователя.
Предупреждение C4311. Пример 1
«приведение типа»: усечение указателя из «void * _ _ ptr64» в «Long без знака
pPciAddr->u.AsULONG = (ULONG) CIA_PCI_CONFIG_BASE_QVA;
Птртаулонг — это встроенная функция или макрос в зависимости от используемого использования. Он усекает указатель до ulong. Хотя 32-разрядные указатели не затрагиваются, верхняя половина 64-разрядного указателя усекается.
CIA _ _ Конфигурация PCI _ Базовая _ кВА объявляется как PVOID. Приведение ulong работает в 32-разрядном мире, но приводит к ошибке в 64-разрядном мире. Решением является получение 64-разрядного указателя на ulong, поскольку изменение определения объединения, которое ппЦиаддр->u. асулонг, определено в, изменяет слишком много кода.
Использование макроса птртаулонг для преобразования 64-разрядного PVOID в требуемый ulong разрешено, так как у нас есть сведения о конкретном значении CIA _ PCI _ config _ Base _ кВА. В этом случае этот указатель никогда не будет содержать данные в верхнем 32 бит.
Предупреждение C4311, пример 2
«приведение типа»: усечение указателя из «ошибка структуры» _ _ кадра * _ _ ptr64 «в» Long без знака
Проблема заключается в том, что последний параметр этой функции является указателем на структуру данных. Поскольку Пункорректаблиррор является указателем, он изменяет размер с помощью модели программирования. Прототип для кебугчеккекс был изменен так, чтобы последний параметр был типа ulong _. В результате необходимо привести указатель функции к типу записи _ типа ulong.
Вы можете спросить, почему PVOID не использовался в качестве последнего параметра. В зависимости от контекста вызова последний параметр может быть не указателем или, возможно, кодом ошибки.
Предупреждение C4244, пример 1
«=»: преобразование из » _ компонент конфигурации _ структуры * _ _ ptr64″ в » _ компонент конфигурации _ структуры * «, возможна утрата данных
Функция объявляет компонент переменной в качестве _ компонента пконфигуратион. Позже переменная будет использоваться в следующем назначении, которое отображается правильно:
Однако компонент типа ПКОНФИГУРАТИОН _ определяется следующим образом:
Определение типа для компонента ПКОНФИГУРАТИОН _ предоставляет 32-разрядный указатель как в 32-разрядных, так и в 64-разрядных моделях, так как он объявлен как указатель _ 32. Исходный конструктор этой структуры знал, что он будет использоваться в 32-разрядном контексте в BIOS и явно определен для этого использования. этот код прекрасно работает в 32-разрядных Windows, так как указатели должны быть 32-разрядными. в 64-разрядном Windows он не работает, так как код находится в 64-разрядном контексте.
Чтобы обойти эту проблему, используйте компонент конфигурации, _ * а не 32-разрядный _ компонент пконфигуратион. Очень важно четко понимать назначение кода. Если этот код предназначен для 32 сенсорного управления BIOS или системным пространством, это исправление не будет работать.
Указатель _ 32 определен в нтдеф. h и Winnt. h.
Предупреждение C4242, пример 2
«=»: преобразование » _ _ Int64″ в «без знака Long», возможна утрата данных
Это предупреждение создается потому, что вычисление использует 64-битные значения, в данном случае указатели и помещает результат в 32-разрядный ulong.
Приведение результата позволяет компилятору узнать, что вы уверены в результатах. С другой стороны, убедитесь, что вы понимаете вычисление и уверены, что оно поместится в 32-разрядном ulong.
Если результат может не уместиться в 32-разрядном ulong, измените базовый тип переменной, которая будет содержать результат.
Предупреждение C4311-пример 1
«приведение типа»: усечение указателя из «void * _ _ ptr64» в «unsigned long»
Эта функция работает с адресами в виде целых чисел, что требует обязательного ввода этих целых чисел в переносимом виде. Все локальные переменные, промежуточные значения в вычислениях и возвращаемые значения должны быть переносимыми типами.
Пулонг _ PTR — это указатель, который сам по себе 32 бит для 32-бит Windows и 64 бит для Windows 64-bit. он указывает на целое число без знака _ типа ULONG, которое 32 бит для 32-бит Windows и 64 бит для Windows 64-bit.
Предупреждение C4311-пример 2
«приведение типа»: усечение указателя из «void * _ _ ptr64» в «unsigned long»
Указатель ПЦииоспацебасе содержит кВА, созданный в макросе HAL, _ _ кВА. Этот макрос возвращает 64-разрядное значение с максимальным значением 32, равное нулю, поэтому математические вычисления будут работать. Можно просто оставить код для усечения указателя в ulong, но такой подход не рекомендуется для повышения удобства поддержки и переносимости кода. Например, содержимое кВА может измениться в будущем, чтобы использовать некоторые верхние биты на этом уровне, нарушая код.
Будьте в безопасности и используйте ulong _ ptr для всех математических адресов и указателей.
HalpCMOSRamBase = (PVOID)((ULONG_PTR)PciIoSpaceBase + CMOS_ISA_PORT_ADDRESS);
Предупреждение C4311. Пример 3
«приведение типа»: усечение указателя из «void * _ _ ptr64» в «unsigned long»
Компилятор предупреждает о адресе (&) и операторах сдвига влево (
Предупреждение C4311. Пример 4
«приведение типа»: усечение указателя из «void * _ _ ptr64» в «unsigned long»
Транслатедаддресс — это объединение, которое выглядит примерно следующим образом:
Зная, что остальная часть кода может поместиться в Хигхпарт, мы можем выбрать любое из приведенных здесь решений.
С осторожностью мы могли бы использовать следующее:
Это работает в этом примере: макрос халкреатеква возвращает 64 бит, а верхние 32-биты имеют нулевое значение. Просто будьте внимательны, чтобы не оставлять верхние 32 бит, не применяя в 32-разрядной среде, которая может фактически выполняться в этом втором решении.
Предупреждение C4311. Пример 5
«приведение типа»: усечение указателя из «void * _ _ ptr64» в «unsigned long»
Виндоврегистерс->Виндовбасе является указателем и теперь имеет 64 бит. В коде написано, что это значение равно 20 битам сдвига вправо. Компилятор не позволяет использовать оператор сдвига вправо (>>) для указателя; Поэтому необходимо привести его к целому числу.
Wbase.Wbase= PtrToUlong ( (PVOID) ((ULONG_PTR) (WindowRegisters->WindowBase) >> 20));
Устранение неполадок Microsoft Visual C++ компилятором или линкером Visual C++
В этой статье содержится разрешение устранения неполадок для компиляторов Visual C++ или Visual C++ Linker.
Применяется к: Microsoft Visual C++ 2010 Express, Visual Studio
Исходный номер КБ: 974229
Действие
При расследовании возможной проблемы с компилятором Microsoft Visual C++ или линкером важно получить как можно больше сведений о процессе сборки и используемых параметрах. В этой статье рассмотрены некоторые советы по устранению неполадок, которые помогут решить проблему сборки или получить всестороннюю информацию для службы поддержки Майкрософт.
Решение
Для проблем компилятора, таких как внутренние ошибки компилятора (т. е. C1001), зависает или сбои, может быть полезно захватить выход препроцессора C/C++ для предоставления упрощенного репродуцируемый пример проблемы. В Visual C++ IDE это можно сделать, задав свойство Generate Preprocessed File with Line Numbers (/P) или Without Line Numbers (/EP/P). Это свойство можно найти на страницах свойств проекта в параметрах Configuration Properties, C/C++, Preprocessor.
Переключатель компилятора /P направляет CL.EXE для захвата вывода препроцессора в файл. Добавление /EP подавляет добавление сведений о номере строки в итоговом файле. /P достаточно, но /EP/P создает меньший файл вывода. Созданный файл вывода препроцессора будет иметь то же имя, что и исходный файл, который компилирован, но с расширением файла a.i, например, file1.cpp создает файл вывода препроцессора file1.i в том же каталоге.
Проблемы со ссылками
Для проблем со ссылками (ошибки типа LNKxxxxx) можно использовать командный переключатель командной строки /LINKREPRO для создания тестового случая, содержащего только входные данные ссылок без зависимости от исходных файлов. /LINKREPRO использует следующий синтаксис:
‘ это полный путь к пустой папке в локальной файловой системе. Эта папка уже должна существовать — ссылка не создаст ее автоматически и создаст ошибку, если папка не существует.
Если в этом окне редактирования уже есть другие параметры линкера, разделяйте их запятой.
Кроме того, можно использовать переменную LINK_REPRO среды. Если переменная среды существует, линкатор будет читать выходной путь из переменной среды и LINK_REPRO создавать linkrepro. Переключатель /LINKREPRO не требуется при использовании LINK_REPRO переменной среды. Использование LINK_REPRO переменной среды:
Откройте командную Visual Studio командную подсказку. Это устанавливается в меню Пуск, в Visual Studio папке под Инструменты Visual Studio подмастерье.
Запустите Visual Studio из той же командной подсказки, чтобы она разделяет копию измененной среды.
Откройте проект и перестроим весь проект.
Когда LINK.EXE вызывается в сборке, она копирует все необходимое для привязки проекта к каталогу linkrepro. Среди скопированные файлы будут ваши объектные файлы (. OBJ), необходимые файлы библиотеки (. LIB), включая библиотеки Майкрософт и файл ответа linker (LINK. RSP), чтобы ССЫЛКА больше не зависела от файла решения.
Этот процесс также можно использовать для проверки файлов, участвующих в создании библиотеки, при использовании LIB.EXE link/LIB.
Заявление об отказе от ответственности
Быстрый отказ от публикации
Статьи быстрого публикации предоставляют сведения непосредственно из организации поддержки Майкрософт. Сведения, содержащиеся в этом ниже, создаются в ответ на возникающие или уникальные темы или предназначены для дополнения других сведений базы знаний.
Заявление об отказе от ответственности
Корпорация Майкрософт и(или) ее поставщики не делают никаких представлений или гарантий относительно пригодности, надежности или точности сведений, содержащихся в документах и связанных с ними графиках, опубликованных на этом сайте («материалы») для любых целей. Эти материалы могут включать технические неточности или опечатки и могут быть пересмотрены в любое время без уведомления.
В максимальной степени, разрешенной применимым законодательством, Корпорация Майкрософт и/или ее поставщики дисклеймировали и исключали все представления, гарантии и условия, будь то экспресс- или подразумеваемые или нормативные, включая представления, гарантии или условия названия, отсутствие нарушения, удовлетворительное состояние или качество, торговая доступность и пригодность для определенной цели, в отношении материалов.
Ошибки компиляции
ПРИМЕЧАНИЕ: Эти ошибки обычно не выводят окно и просто показывают » Build Failed » в выводе компилятора. Если появляется окно, то это обычно ошибка Runner Error, которая объясняется здесь.
Все сообщения об ошибках компилятора будут иметь одинаковый формат:
Если ошибка найдена в сценарии, то это будет просто:
Затем вы можете дважды щелкнуть на любой из записей об ошибке компилятора, чтобы открыть данный актив в позиции, отмеченной как дающая ошибку, и затем вы можете использовать информацию, содержащуюся в сообщении. можно использовать информацию, содержащуюся в сообщении, чтобы точно определить, где именно в объекте или сценарии произошла ошибка. Однако иногда эти ошибки могут показаться немного загадочными, поэтому ниже вы найдете полный список всех ошибок и краткое объяснение того, что они означают:
Разное
Струны
Скрипты, Функции и аргументы
Ожидаемые символы/значения
Ошибки и предупреждения компилятора и средств сборки C/C++
В статьях, приведенных в этом разделе документации, объясняются сообщения об ошибках и предупреждения диагностики, созданные компилятором Microsoft C/C++ и средствами сборки.
компиляторы Visual Studio и средства сборки могут сообщать о различных типах ошибок и предупреждений. После обнаружения ошибки или предупреждения средства сборки могут сделать предположения о намерениях кода и попытаться продолжить, чтобы в одно и то же время можно было сообщить больше проблем. Если средства делают неверное предположение, последующие ошибки или предупреждения не могут применяться к проекту. При устранении проблем в проекте всегда начинайте с первой зарегистрированной ошибки (или предупреждения) и выполняйте повторную сборку как можно чаще. Одно из исправлений может привести к удалению нескольких последующих ошибок.
Ссылки на дополнительные ресурсы справки и сообщества см. в разделе Visual C++ справки и Community.
В этом разделе
Ошибки и предупреждения BSCMAKE (BKxxxx)
Ошибки и предупреждения, создаваемые служебной программой «Просмотр информации» (BSCMAKE.EXE).
Ошибки и предупреждения командной строки
Ошибки и предупреждения, создаваемые средствами сборки для параметров командной строки.
Предупреждения компилятора с C4000 по C5999
Предупреждения для проблем, обнаруженных компилятором C++ (CL.EXE).
Предупреждения компилятора по версиям компилятора
Список предупреждений, появившихся каждой версией компилятора.
Ошибки среды выполнения C (Rxxxx)
Ошибки, формируемые во время выполнения библиотекой времени выполнения C (CRT).
Ошибки и предупреждения CVTRES (CVTxxxx)
Ошибки и предупреждения, созданные с помощью файла ресурсов Майкрософт в программе преобразования объектов COFF (CVTRES.EXE).
Ошибки вычислителя выражений (CXXxxxx)
Ошибки, создаваемые отладчиком и средствами диагностики.
Ошибки и предупреждения средств компоновщика (LNKxxxx)
Ошибки и предупреждения, созданные компоновщиком и связанными инструментами (LINK.EXE, LIB.EXE, DUMPBIN.EXE, EDITBIN.EXE).
Математические ошибки (Mxxxx)
Ошибки, создаваемые математической библиотекой среды выполнения с плавающей запятой.
Ошибки и предупреждения NMAKE (Uxxxx)
Ошибки и предупреждения, создаваемые инструментом Microsoft Makefile (NMAKE.EXE).
Ошибки и предупреждения профильной оптимизации (Пгкскскскс)
Ошибки и предупреждения, созданные средствами оптимизации Profile-Guided (PGO).
Ошибки и предупреждения режима сборки проекта (PRJxxxx)
ошибки и предупреждения, созданные в машинном коде C++ Project системы сборки в Visual Studio.
Сообщения векторизатора и параллелизатора
Диагностические сообщения, создаваемые параметрами компилятора векторизатора и параллелизатора Optimization.
Существуют ли какие-либо компиляторы, которые пытаются исправить синтаксические ошибки самостоятельно? [закрыто]
Некоторое время назад я слышал, что раньше был компилятор, который пытался исправить синтаксические ошибки, анализируя контекст и выводя то, что предполагалось.
Такой компилятор действительно существует? Очевидно, что это имеет небольшое практическое значение, но было бы очень интересно играть и учиться.
Так что нет, на самом деле таких компиляторов нет, потому что вопрос не имеет смысла. Угадайте, что синтаксические ошибки должны делать согласно некоторому набору правил, становится частью синтаксиса.
В этом смысле, есть хороший пример компилятора, который делает это: любой компилятор Си. Они часто просто распечатывают предупреждение о том, что не так, как должно быть, а затем предполагают, что вы имели в виду X, и продолжайте. На самом деле это «угадывание» нечеткого кода (хотя это, по большей части, не синтаксис как таковой), то, что с таким же успехом могло бы остановить компиляцию с ошибкой и, следовательно, квалифицироваться как ошибка.
Звучит действительно опасно. Если компилятор попытается определить ваше намерение, сделает неверный вывод, исправит код, а затем не сообщит вам (или сообщит вам в каком-то предупреждении, что вы, как и все остальные, игнорируете), то вы собираетесь запустить код, который может серьезно причинить ущерб.
Подобный компилятор, вероятно, очень намеренно НЕ создан.
В среде IDE для языка программирования обычно в наши дни есть компилятор, работающий в фоновом режиме, так что он может предоставлять услуги анализа, такие как окрашивание синтаксиса, IntelliSense, ошибки и так далее. Очевидно, что такой компилятор должен уметь понимать глубоко испорченный код; Большую часть времени при редактировании код не является правильным. Но мы все еще должны понять это.
Однако обычно функция восстановления после ошибок используется только во время редактирования; не имеет смысла допускать это для фактической компиляции в сценариях «mainline».
Нельзя сказать, что это не могло сделать лучшую работу. Если бы он посмотрел вперед на следующую строку, то он мог бы сделать более точное предположение о намерении программиста, но в конце концов, если есть несколько допустимых путей, по которым синтаксис мог бы пойти, тогда действительно нет замены для программиста, являющегося явным.
Мне кажется, что если компилятор может исправить неправильный синтаксис, то этот синтаксис должен быть задокументирован на языке.
Причина синтаксических ошибок заключается в том, что парсер не может создать абстрактное синтаксическое дерево из программы. Это происходит, когда токен не на своем месте. Чтобы угадать, где должен находиться этот токен, должен ли он быть удален или если для исправления ошибки должен быть добавлен какой-либо другой токен, вам понадобится компьютер, который может угадать намерения программиста. Как машина могла догадаться, что:
Эта технология еще не существует.
Хотя это не совсем то же самое, именно поэтому HTML превратился в катастрофу. Браузеры терпели плохую разметку, и следующее, что вы знали, браузер A не мог отображать так же, как браузер B (да, есть и другие причины, но это была одна из лучших причин, особенно 10 лет назад, до того, как некоторые из правил расшатанности стали общепринятыми ).
Как делает вывод Эрик Липперт, многие из этих вещей лучше всего обрабатываются в IDE, а не в компиляторе. Это позволяет вам увидеть, что автоматические биты пытаются испортить для вас.
Стратегия, которая, на мой взгляд, является преобладающей, заключается в непрерывном уточнении языка вместо ослабления компилятора: если это действительно то, что компилятор может выяснить автоматически, то введите четко определенную языковую конструкцию вокруг него.
Что заставляет меня задуматься: большинство языков стилей Си уже делают это до некоторой степени. Для вещей, которые могут быть выяснены автоматически, просто уточните синтаксис:
Может быть уменьшено до:
В конце концов, я думаю, что это сводится к следующему: тенденция в том, что вы не делаете компилятор «умнее» или «слабее». Это язык, который сделан умнее или слабее.
Кроме того, слишком много «помощи» может быть опасно, например, классическая ошибка «if»:
Целью компилятора является создание исполняемых файлов, которые ведут себя как нужно. Если программист пишет что-то, что является недопустимым, даже если компилятор может с 90% вероятностью угадать, что было задумано, обычно лучше, чтобы программист исправил программу, чтобы прояснить намерение, чем чтобы компилятор выполнил и выполнил исполняемый файл который имел бы значительный шанс скрыть ошибку.
Конечно, языки, как правило, должны быть спроектированы таким образом, чтобы код, который четко выражает намерение, был законным, а код, который явно не выражает намерение, должен быть запрещен, но это не значит, что это так. Рассмотрим следующий код [Java или C #]
Наихудшими видами языковых правил являются те, в которых компиляторы будут делать выводы в тех случаях, когда что-то не может законным образом компилироваться иначе, но когда программа может «случайно» быть действительной в том случае, когда предполагался вывод. Многие ситуации, связанные с неявным завершением оператора, попадают в эту категорию. Если программист, который намеревается написать два отдельных оператора, пропускает терминатор оператора, компилятору обычно удается вывести границу оператора, но иногда он может рассматривать как один оператор что-то, что должно было быть обработано как два.
Синтаксические ошибки особенно трудно исправить. Возьмите случай пропущенного права ) : мы знаем, что мы можем исправить код, вставив его, но обычно есть много мест, где мы могли бы вставить один и получить синтаксически правильную программу.
Гораздо проще указать идентификаторы с ошибками (но учтите, что это не синтаксические ошибки). Можно вычислить расстояние редактирования между неразрешимым идентификатором и всеми идентификаторами в области видимости, и, заменив неразрешимое слово тем, которое, скорее всего, имел в виду пользователь, во многих случаях можно было бы найти правильную программу. Однако оказывается, что все же лучше пометить ошибку и позволить IDE предложить допустимые замены.
Такой компилятор был бы просто непринужденной, нестандартной реализацией любого языка, который он компилирует.
Это было опробовано несколько раз, но часто оно не давало желаемого эффекта: например, HAL 9000 или GlaDOS.
- Непрожитые фулл стики что это
- справка о доходах физического лица что это такое