Ошибки и предупреждения препроцессора

Компилятор создает следующие ошибки для неправильного использования директив препроцессора:

  • CS1024: ожидаемая директива препроцессора
  • CS1025: ожидается однострочный комментарий или конец строки
  • CS1027: ожидается директива #endif
  • CS1028: непредвиденная директива препроцессора
  • CS1029: #error: "text"
  • CS1030: #warning: "text"
  • CS1032: не удается определить или отменить символы препроцессора после первого маркера в файле
  • CS1038: ожидается директива #endregion
  • CS1040: директивы препроцессора должны отображаться как первый символ, отличный от пробела в строке
  • CS1517: недопустимое выражение препроцессора
  • CS1560: недопустимое имя файла, указанное для директивы препроцессора. Имя файла слишком длинное или недопустимое имя файла
  • CS1576: номер строки, указанный для директивы #line, отсутствует или недопустим
  • CS1578: имя файла, однострочный комментарий или ожидаемый конец строки
  • CS1633: неразпознанная директива #pragma
  • CS1634: ожидаемое отключение или восстановление
  • CS1635: не удается восстановить предупреждение "предупреждающий код", так как он был отключен глобально
  • CS1691: 'номер' не является допустимым номером предупреждения
  • CS1692: недопустимое число
  • CS1694: недопустимое имя файла, указанное для директивы препроцессора. Имя файла слишком длинное или недопустимое имя файла
  • CS1695: Некорректный синтаксис #pragma checksum; должно быть #pragma checksum "имя файла" "{XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}" "XXXX..."
  • CS1696: ожидается однострочный комментарий или конец строки
  • CS1709: имя файла, указанное для директивы препроцессора, пусто
  • CS7009: не удается использовать #r после первого маркера в файле
  • CS7010: ожидается имя файла в кавычках
  • CS7011: #r разрешено только в сценариях
  • CS8097: #load разрешено только в сценариях
  • CS8098: не удается использовать #load после первого маркера в файле
  • CS8301: недопустимое имя для символа предварительной обработки; "Имя символа" не является допустимым идентификатором
  • CS8938: значение директивы #line отсутствует или не находится в допустимом диапазоне
  • CS8939: положение конца директивы #line должно быть больше или равно начальной позиции.
  • CS8996: необработанные строковые литералы не допускаются в директивах препроцессора
  • CS9028: директива #line диапазона требует пробела перед первой скобкой, перед смещением символов и перед именем файла
  • CS9297: #: директивы не могут быть после первого маркера в файле
  • CS9298: #: директивы можно использовать только в файловых приложениях (-features:FileBasedProgram)
  • CS9299: #: директивы не могут быть после #if директивы
  • CS9314: #! директивы можно использовать только в сценариях или приложениях на основе файлов.
  • CS9378: "#!" должен быть первым символом в первой строке файла.

Недопустимый синтаксис директивы препроцессора

  • CS1024: ожидаемая директива препроцессора
  • CS1025: ожидается однострочный комментарий или конец строки
  • CS1027: ожидается директива #endif
  • CS1028: непредвиденная директива препроцессора
  • CS1032: не удается определить или отменить символы препроцессора после первого маркера в файле
  • CS1038: ожидается директива #endregion
  • CS1040: директивы препроцессора должны отображаться как первый символ, отличный от пробела в строке
  • CS1517: недопустимое выражение препроцессора
  • CS1633: Нераспознанная директива #pragma
  • CS1696: ожидается однострочный комментарий или конец строки
  • CS8996: необработанные строковые литералы не допускаются в директивах препроцессора

Эти ошибки указывают на то, что для директив препроцессора использовался недопустимый синтаксис. Наиболее вероятные причины:

  • Использование нераспознанной директивы после # (CS1024, CS1633).
  • Включая многострочные комментарии в строках директив (CS1025, CS1696).
  • Использование директив в неожиданных местах (CS1028).
  • Отсутствуют необходимые директивы сопоставления (CS1027, CS1038).
  • Размещение директивы #define или #undef после первого токена в файле (CS1032).
  • Неправильное размещение директивы в качестве первого токена в строке (CS1040).
  • Использование недопустимых выражений в условной компиляции (CS1517).
  • Использование необработанных строковых литералов в директивах препроцессора (CS8996).

Пример CS1024 — ожидаемая директива препроцессора:

#import System   // CS1024 - "import" is not a valid directive

Пример CS1025 — ожидается однострочный комментарий или конец строки:

#if true /* hello  
*/   // CS1025 - multiline comment not allowed
#endif

Пример CS1027 — ожидается директива #endif:

#if true   // CS1027 - missing #endif
class Test { }

Пример CS1028 — непредвиденная директива препроцессора:

#endif   // CS1028 - no matching #if

Пример CS1032 — #define и #undef директивы препроцессора должны отображаться перед другими токенами:

class Test { }
#define X   // CS1032 - directive appears after the first token

Чтобы устранить эту ошибку, поместите все #define и #undef директивы перед первым маркером в файле:

#define X
#undef Y
class Test { }

Пример CS1038 — ожидается директива #endregion:

#region testing
class Test { }
// CS1038 - missing #endregion

Пример CS1040. Директивы препроцессора должны отображаться как первый символ, отличный от пробела:

/* Comment */ #define X   // CS1040 - directive not first on line

Пример CS1517 — недопустимое выражение препроцессора:

#if 1           // CS1517 - numeric literals not allowed
#endif
#if ~symbol     // CS1517 - bitwise operators not allowed  
#endif

Пример CS1633 — нераспознанная директива #pragma:

#pragma unknown  // CS1633 - "unknown" is not a valid pragma

Пример CS8996. Необработанные строковые литералы не допускаются в директивах препроцессора:

// CS8996.cs
#pragma checksum """raw_string""" "{406EA660-64CF-4C82-B6F0-42D48172A799}" "hash"  // CS8996
class Test { }

Чтобы устранить эту ошибку, используйте обычный строковый литерал:

#pragma checksum "filename.cs" "{406EA660-64CF-4C82-B6F0-42D48172A799}" "hash"  // OK
class Test { }

Чтобы устранить эти ошибки, убедитесь, что директивы препроцессора соответствуют правильным правилам синтаксиса, описанным в документации по директивам препроцессора.

Недопустимые имена символов препроцессора

  • CS8301: недопустимое имя для символа предварительной обработки; "Имя символа" не является допустимым идентификатором

При создании CSharpParseOptions программно укажите каждый символ условной компиляции в виде одного имени идентификатора. Первый символ должен быть допустимым в начале идентификатора C#, а остальные символы должны быть допустимыми символами идентификаторов. Roslyn также принимает текст ключевого слова в качестве имени символа, но не добавляйте префикс @. Не включайте пробелы, знаки препинания, такие как . или -, оператор присваивания, такой как FEATURE=1, или полное условное выражение.

Символ препроцессора фиксирует только то, определено ли его имя. Он не сохраняет значение. Недопустимые имена, переданные через свойство проекта DefineConstants или параметр компилятора -define, вместо этого приводят к ошибке CS2029; см. DefineConstants.

ошибки директивы #error и #warning

  • CS1029: #error: "text"
  • CS1030: #warning: "text"
  • CS1634: ожидаемое отключение или восстановление
  • CS1635: не удается восстановить предупреждение "предупреждающий код", так как он был отключен глобально
  • CS1691: "number" не является допустимым номером предупреждения
  • CS1692: недопустимое число

Эти ошибки возникают, когда компилятор обрабатывает #error#warningи #pragma warning директивы. Эти директивы позволяют создавать пользовательские сообщения об ошибках и предупреждениях во время компиляции и управления предупреждениями.

CS1029 отображает текст ошибки, определенной директивой #error :

// CS1029.cs
class Sample
{
   static void Main()
   {
      #error Let's give an error here   // CS1029
   }
}

В результате компиляции формируются следующие результаты:

example.cs(9,8): error CS1029: #error: 'Let's give an error here   // CS1029  '

CS1030 отображает текст предупреждения, определенного директивой #warning :

// CS1030.cs
class Sample
{
   static void Main()
   {
      #warning Let's give a warning here
   }
}

В результате компиляции формируются следующие результаты:

example.cs(6,16): warning CS1030: #warning: 'Let's give a warning here'

CS1634 возникает, когда #pragma warning директива плохо сформирована, например, если пропущены команды отключения или восстановления.

// CS1634.cs
// compile with: /W:1

#pragma warning   // CS1634
// Try this instead:
// #pragma warning disable 0219

class MyClass
{
  public static void Main()
  {
  }
}

CS1635 возникает при использовании параметра командной строки или параметра проекта для глобального /nowarn отключения предупреждения, но используется #pragma warning restore для восстановления этого предупреждения:

// CS1635.cs
// compile with: /w:1 /nowarn:162

enum MyEnum {one=1,two=2,three=3};

class MyClass
{
    public static void Main()
    {
#pragma warning disable 162

    if (MyEnum.three == MyEnum.two)
        System.Console.WriteLine("Duplicate");

#pragma warning restore 162  // CS1635
    }
}

CS1691 возникает, когда число, переданное #pragma warning директиве, не является допустимым номером предупреждения:

// CS1691.cs
public class C
{
    int i = 1;
    public static void Main()
    {
        C myC = new C();
#pragma warning disable 151  // CS1691
// Try the following line instead:
// #pragma warning disable 1645
        myC.i++;
#pragma warning restore 151  // CS1691
// Try the following line instead:
// #pragma warning restore 1645
    }
}

CS1692 возникает, когда число в директивах препроцессора, например #pragma и #line недопустимо, так как оно слишком велико, в неправильном формате или содержит недопустимые символы:

// CS1692.cs

#pragma warning disable a  // CS1692
// Try this instead:
// #pragma warning disable 1691

class A
{
    static void Main()
    {
    }
}

Эти директивы полезны для сценариев условной компиляции, в которых разработчики хотят оповещать разработчиков о конкретных условиях в коде или контролировать, какие предупреждения отображаются во время компиляции. Дополнительные сведения об использовании этих директив см. в документации по директивам препроцессора и предупреждению #pragma.

#line и ошибки директив файла

  • CS1560: недопустимое имя файла, указанное для директивы препроцессора. Имя файла слишком длинное или недопустимое имя файла.
  • CS1576: номер строки, указанный для директивы #line, отсутствует или недопустим.
  • CS1578: имя файла, однострочный комментарий или ожидаемый конец строки.
  • CS1694: недопустимое имя файла, указанное для директивы препроцессора. Имя файла слишком длинное или недопустимое имя файла.
  • CS1695: Недопустимый синтаксис директивы #pragma checksum; должно быть: #pragma checksum "filename" "{XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}" "XXXX...".
  • CS1709: имя файла, указанное для директивы препроцессора, пусто.
  • CS8938: Значение директивы #line отсутствует или выходит за допустимый диапазон.
  • CS8939: положение конца директивы #line должно быть больше или равно начальной позиции.
  • CS9028: Директива диапазона #line требует пробела перед первой скобкой, перед смещением символа и перед именем файла.

Эти ошибки указывают на неправильное #line использование директив или директив препроцессора, связанных с файлами. Наиболее вероятные причины:

  • Недопустимые или отсутствующие имена файлов (CS1560, CS1694, CS1709).
  • Неправильный формат номеров строк или значений (CS1576, CS8938, CS8939).
  • Отсутствует правильный синтаксис для имен файлов и комментариев (CS1578).
  • Неправильный #pragma checksum синтаксис (CS1695).
  • Неправильное интервалирование в #line директивах диапазона (CS9028).

Пример CS1560/CS1694 — недопустимое имя файла:

#line 100 "MyFile1234567890MyFile1234567890MyFile1234567890MyFile1234567890MyFile1234567890MyFile1234567890MyFile1234567890MyFile1234567890MyFile1234567890MyFile1234567890MyFile1234567890MyFile1234567890MyFile1234567890MyFile1234567890MyFile1234567890MyFile1234567890.txt"   // CS1560/CS1694 - filename too long

Пример CS1576 — номер строки отсутствует или недопустим:

#line "abc.sc"         // CS1576 - missing line number
#line abc "file.cs"    // CS1576 - invalid line number format

Пример CS1578 — имя файла, комментарий или ожидаемый конец строки:

#line 101 abc.cs   // CS1578 - filename not quoted

Пример CS1695 — недопустимый синтаксис контрольной суммы #pragma:

#pragma checksum "12345"  // CS1695 - missing GUID and checksum

Пример CS1709 — пустое имя файла:

#pragma checksum "" "{406EA660-64CF-4C82-B6F0-42D48172A799}" ""  // CS1709 - empty filename

Пример CS8938 — значение директивы #line отсутствует или выходит за пределы допустимого диапазона:

#line   // CS8938 - missing value
#line 0  // CS8938 - out of range (must be 1-16,707,566)

Пример CS8939 — ошибка в позиции конца директивы #line:

#line (1, 10) - (1, 5) "file.cs"  // CS8939 - end column < start column

Пример CS9028 — интервалы директив диапазона #line:

#line(1, 1) - (1, 10)"file.cs"  // CS9028 - missing spaces

Чтобы устранить эти ошибки, убедитесь, что #line директивы и директивы препроцессора, связанные с файлами, соответствуют правильному синтаксису, как описано в документации по директивам препроцессора.

Неправильное использование директив приложений на основе файлов

  • CS9297: #: директивы не могут быть после первого токена в файле
  • CS9298: #: директивы можно использовать только в файловых приложениях (-features:FileBasedProgram)
  • CS9299: #: директива не может следовать за #if директивой
  • CS9314: #! директивы можно использовать только в сценариях или приложениях на основе файлов.
  • CS9378: "#!" должен быть первым символом в первой строке файла.

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

Строка shebang (#!) указывает исполняемый файл для скрипта или приложения, запускаемого из файла. Поместите его в первый знак первой строки перед любым пробелом, комментариями или пустыми строками (CS9378); см. руководство по директиве приложения на основе файлов.

Файл содержит директивы script.cs

Следующие ошибки указывают на неправильное использование или размещение директив скрипта C#:

  • CS7009: не удается использовать #r после первого маркера в файле
  • CS7010: ожидаемое имя файла с кавычками
  • CS7011: #r разрешено только в сценариях
  • CS8097: #load разрешено только в сценариях
  • CS8098: не удается использовать #load после первого маркера в файле

В скрипте C# (.csx) директива #load после токена вызывает CS8098:

System.Console.WriteLine("This is the first token.");
#load "helpers.csx" // CS8098

Чтобы исправить CS8098, переместите каждую директиву перед каждым #load токеном в скрипте:

#load "helpers.csx"
System.Console.WriteLine("The directive precedes the first token.");

В обычном исходном файле C# (.cs) #load запрещено. Это связанное условие создает CS8097, а не CS8098. Удалите #load из обычных исходных файлов.