Pragma c что это
Перейти к содержимому

Pragma c что это

  • автор:

 

Директивы препроцессора в C#

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

Директивы препроцессора — это команды компилятора, которые влияют на процесс его работы.

Эти команды определяют, какие блоки кода нужно компилировать или как, например, обрабатывать определенные ошибки и предупреждения.

Директива препроцессора C# начинается с символарешетки # и не может занимать более одной строки. Директивы заканчиваются символом новой строкой, а не точкой с запятой ; .

Директива

Описание

Синтаксис

Проверяет, является ли препроцессорное выражение истинным или нет.

Используется вместе с #if для проверки нескольких препроцессорных выражений.

Используется вместе с #if для создания условных ветвлений.

Используется вместе с #if для обозначения конца условной директивы.

Используется для определения идентификатора

Используется для отмены определения идентификатора.

Позволяет генерировать предупреждение 1 уровня из кода.

Позволяет генерировать ошибку из кода.

Используется для задания номера строки и имени файла, сообщаемого макросами препроцессора.

Позволяет обозначить область, которую можно развернуть или свернуть при использовании редактора кода Visual Studio.

Закрывает область, определенную директивой #region .

Дает компилятору специальные инструкции для компиляции файла, в котором он работает.

  • Директива #define позволяет определять идентификатор.
  • Идентификаторы, которые были определены при использовании #if , будут иметь значение true .
  • Идентификаторы могут использоваться для указания условий компиляции.
Синтаксис
Пример использования

Здесь TESTING — это идентификатор.

Директива #if

  • Директива #if используется для проверки препроцессорного выражения.
  • Препроцессорное выражение состоит из комбинации идентификаторов и таких операторов, как && (И), || (ИЛИ), ! (НЕ).
  • За директивой #if следует директива #endif .
  • Код внутри директивы #if компилируется только в том случае, если выражение, проверенное с помощью #if истинно.
Синтаксис
Пример использования
Пример 1. Используем директиву #if

Вывод:

В приведенной выше программе идентификатор CSHARP определяется с помощью директивы #define в начале программы. Внутри метода Main() директива #if используется для проверки истинности CSHARP. Блок кода внутри директивы #if компилируется, только если CSHARP определен.

Директива #elif

  • Директива #elif используется вместе с директивой #if , которая позволяет нам создавать составное условие.
  • #elif используется при тестировании нескольких препроцессорных выражений.
  • Код внутри директивы #elif компилируется только в том случае, если выражение, проверенное с помощью #elif истинно.
Синтаксис
Пример использования

Директива #else

  • Директива #else используется вместе с директивой #if .
  • Если ни одно из выражений в предыдущих директивах #if и #elif не является истинным, будет скомпилирован код внутри директивы #else .
Синтаксис
Пример использования

Директива #endif

  • Директива #endif используется для обозначения конца директивы #if .
Синтаксис
Пример использования
Пример 2. Используем условные директивы (#if, #elif, #else, #endif)

Вывод:

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

Директива #warning

  • Директива #warning позволяет генерировать предупреждение 1 уровня.
Синтаксис
Пример 3. Используем директиву #warning

Вывод:

После запуска программы мы увидим результат, указанный выше. Текст представляет собой предупреждающее сообщение. Здесь мы определяем и генерируем предупреждение с помощью директивы #warning .

Обратите внимание, что операторы после директивы #warning также выполняются. Это означает, что директива #warning не завершает программу, а просто выдает предупреждение.

Директива #error

  • Директива #error позволяет генерировать ошибку.
Синтаксис
Пример 4. Используем директиву #error

Вывод:

Программа завершится, и C# не напечатает строку «пример директивы #error» не будет напечатана, как это было в директиве #warning .

Директива #line

  • Директива #line используется для задания номера строки и имени файла, сообщаемого макросами препроцессора.
Синтаксис
Пример использования
Пример 5. Используем директиву #line

Вывод:

Мы сохранили приведенный выше пример как Program.cs . Предупреждение было фактически сгенерировано программой Program.cs в строке 10. Используя директиву #line , мы изменили номер строки на 200, а имя файла — на AnotherProgram.cs .

Директива #region и #endregion

  • Директива #region позволяет нам определять блок кода, который можно будет сворачивать и разворачивать при использовании редактора кода Visual Studio.
  • Эта директива используется для структурирования кода.
  • Блок #region не может пересекаться с блоком #if. Однако блок #region можно вложить в блок #if, а блок #if — в блок #region.
  • Директива #endregion должна указываться в конце блока #region.
Синтаксис
Пример 6. Используем директиву #region

Вывод:

Директива #pragma

  • Директива #pragma используется, чтобы дать компилятору некоторые специальные инструкции при компиляции файла, в котором он работает.
  • Инструкция может включать или отключать некоторые предупреждения.
  • C# поддерживает две инструкции #pragma :
    • #pragma warning : используется для включения или отключения предупреждений.
    • # pragma checksum : генерирует контрольные суммы для исходных файлов, которые будут использоваться при отладке.
    Синтаксис
    Пример использования
    Пример 7. Используем директиву #pragma

    Вывод:

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

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

    Мы также можем отключить конкретное предупреждение вместо всех предупреждений.

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

    Use of #pragma in C

    MD XF's user avatar

    #pragma is for compiler directives that are machine-specific or operating-system-specific, i.e. it tells the compiler to do something, set some option, take some action, override some default, etc. that may or may not apply to all machines and operating systems.

    See msdn for more info.

    MD XF's user avatar

    #pragma is used to do something implementation-specific in C, i.e. be pragmatic for the current context rather than ideologically dogmatic.

    The one I regularly use is #pragma pack(1) where I’m trying to squeeze more out of my memory space on embedded solutions, with arrays of structures that would otherwise end up with 8 byte alignment.

    Pity we don’t have a #dogma yet. That would be fun 😉

    MD XF's user avatar

    SmacL's user avatar

    I would generally try to avoid the use of #pragmas if possible, since they’re extremely compiler-dependent and non-portable. If you want to use them in a portable fashion, you’ll have to surround every pragma with a #if / #endif pair. GCC discourages the use of pragmas, and really only supports some of them for compatibility with other compilers; GCC has other ways of doing the same things that other compilers use pragmas for.

    For example, here’s how you’d ensure that a structure is packed tightly (i.e. no padding between members) in MSVC:

    Here’s how you’d do the same thing in GCC:

    The GCC code is more portable, because if you want to compile that with a non-GCC compiler, all you have to do is

    Whereas if you want to port the MSVC code, you have to surround each pragma with a #if / #endif pair. Not pretty.

    Директивы препроцессора

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

    Все директивы препроцессора начинаются со знака #. Кроме того, каждая директива препроцессора должна быть выделена в отдельную строку кода. Принимая во внимание современную объектно-ориентированную архитектуру языка C#, потребность в директивах препроцессора в нем не столь велика, как в языках программирования предыдущих поколений. Тем не менее они могут быть иногда полезными, особенно для условной компиляции. В этой статье все директивы препроцессора рассматриваются по очереди.

     

    Директива #define

    Директива #define определяет последовательность символов, называемую идентификатором. Присутствие или отсутствие идентификатора может быть определено с помощью директивы #if или #elif и поэтому используется для управления процессом компиляции. Ниже приведена общая форма директивы #define:

    Обратите внимание на отсутствие точки с запятой в конце этого оператора. Между директивой #define и идентификатором может быть любое количество пробелов, но после самого идентификатора должен следовать только символ новой строки. Так, для определения идентификатора EXPERIMENTAL служит следующая директива:

    В C/C++ директива #define может использоваться для подстановки исходного текста, например для определения имени значения, а также для создания макрокоманд, похожих на функции. А в C# такое применение директивы #define не поддерживается. В этом языке директива #define служит только для определения идентификатора.

    Директивы #if и #endif

    Обе директивы, #if и #endif, допускают условную компиляцию последовательности кода в зависимости от истинного результата вычисления выражения, включающего в себя один или несколько идентификаторов. Идентификатор считается истинным, если он определен, а иначе — ложным. Так, если идентификатор определен директивой #define, то он будет оценен как истинный. Ниже приведена общая форма директивы #if:

    Если идентификаторное_выражение, следующее после директивы #if, истинно, то компилируется код (последовательность операторов), указываемый между ним и директивой #endif. В противном случае этот промежуточный код пропускается. Директива #endif обозначает конец блока директивы #if. Идентификаторное выражение может быть простым, как наименование идентификатора. В то же время в нем разрешается применение следующих операторов: !, ==, !=, && и ||, а также круглых скобок.

    Ниже приведен пример применения упомянутых выше директив:

    Пример использования директив #if #endif

    Директивы #else и #elif

    Директива #else действует аналогично условному оператору else языка C#, определяя альтернативный ход выполнения программы, если этого не может сделать директива #if.

    Обозначение #elif означает «иначе если», а сама директива #elif определяет последовательность условных операций if-else-if для многовариантной компиляции. После директивы #elif указывается идентификаторное выражение. Если это выражение истинно, то компилируется следующий далее кодовый блок, а остальные выражения директивы #elif не проверяются. В противном случае проверяется следующий по порядку блок. Если же ни одну из директив #elif не удается выполнить, то при наличии директивы #else выполняется последовательность кода, связанная с этой директивой, а иначе не компилируется ни один из кодовых блоков директивы #if.

    Ниже приведена общая форма директивы #elif:

    Давайте добавим в предыдущий пример следующий код:

    Директива #undef

    С помощью директивы #undef удаляется определенный ранее идентификатор. Это, по существу, означает, что он становится «неопределенным». Ниже приведена общая форма директивы #undef:

    Рассмотрим следующий пример кода

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

    Директива #error

    Директива #error вынуждает компилятор прервать компиляцию. Она служит в основном для отладки. Ниже приведена общая форма директивы #error:

    Когда в коде встречается директива #error, выводится сообщение об ошибке. Например, когда компилятору встречается строка кода « #error Это тестовая ошибка! » компиляция прерывается и выводится сообщение «Это тестовая ошибка!».

    Директива #warning

    Директива #warning действует аналогично директиве #error, за исключением того, что она выводит предупреждение, а не ошибку. Следовательно, компиляция не прерывается. Ниже приведена общая форма директивы #warning:

    Директива #line

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

    Имеются еще два варианта директивы #line. В первом из них она указывается с ключевым словом default, обозначающим возврат нумерации строк в исходное состояние, как в приведенном ниже примере:

    #line default

    А во втором варианте директива #line указывается с ключевым словом hidden. При пошаговой отладке программы строки кода, находящиеся между директивой #line hidden и следующей директивой #line без ключевого слова hidden, пропускаются отладчиком.

    Директивы #region и #endregion

    С помощью директив #region и #endregion определяется область, которая разворачивается или сворачивается при структурировании исходного кода в интегрированной среде разработки Visual Studio. Ниже приведена общая форма этих директив:

    где текст обозначает необязательную символьную строку.

    Директива #pragma

    С помощью директивы #pragma инструкции задаются компилятору в виде опций. Ниже приведена общая форма этой директивы:

    где опция обозначает инструкцию, передаваемую компилятору.

    В текущей версии C# предусмотрены две опции для директивы #pragma. Первая из них, warning, служит для разрешения или запрета отдельных предупреждений со стороны компилятора. Она принимает две формы:

    где предупреждения обозначает разделяемый запятыми список номеров предупреждений. Для отмены предупреждения используется опция disable, а для его разрешения — опция restore.

    Например, в приведенной ниже директиве #pragma запрещается выдача предупреждения №168, уведомляющего о том, что переменная объявлена, но не используется:

    Второй для директивы #pragma является опция checksum. Она служит для формирования контрольной суммы в проектах ASP.NET. Ниже приведена ее общая форма:

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

    Name already in use

    cpp-docs / docs / preprocessor / pragma-directives-and-the-pragma-keyword.md

    • Go to file T
    • Go to line L
    • Copy path
    • Copy permalink
    • Open with Desktop
    • View raw
    • Copy raw contents Copy raw contents

    Copy raw contents

    Copy raw contents

    Pragma directives and the __pragma and _Pragma keywords

    Pragma directives specify machine-specific or operating system-specific compiler features. A line that starts with #pragma specifies a pragma directive. The Microsoft-specific __pragma keyword enables you to code pragma directives within macro definitions. The standard _Pragma preprocessor operator, introduced in C99 and adopted by C++11, is similar.

    #pragma token-string
    __pragma( token-string ) // two leading underscores — Microsoft-specific extension
    _Pragma( string-literal ) // C99

    Each implementation of C and C++ supports some features unique to its host machine or operating system. Some programs, for example, must exercise precise control over the location of data in memory, or control the way certain functions receive parameters. The #pragma directives offer a way for each compiler to offer machine- and operating system-specific features, while maintaining overall compatibility with the C and C++ languages.

    Pragma directives are machine-specific or operating system-specific by definition, and are typically different for every compiler. A pragma can be used in a conditional directive, to provide new preprocessor functionality. Or, use one to provide implementation-defined information to the compiler.

    The token-string is a series of characters representing a specific compiler instruction and arguments, if any. The number sign ( # ) must be the first non-white-space character on the line that contains the pragma. White-space characters can separate the number sign and the word «pragma». Following #pragma , write any text that the translator can parse as preprocessing tokens. The argument to #pragma is subject to macro expansion.

    The string-literal is the input to _Pragma . Outer quotes and leading/trailing whitespace are removed. \» is replaced with » and \\ is replaced with \ .

    The compiler issues a warning when it finds a pragma that it doesn’t recognize, and continues compilation.

    The Microsoft C and C++ compilers recognize the following pragma directives:

    1 Supported only by the C++ compiler.

    Pragma directives and compiler options

    Some pragma directives provide the same functionality as compiler options. When a pragma is reached in source code, it overrides the behavior specified by the compiler option. For example, if you specified /Zp8 , you can override this compiler setting for specific sections of the code with pack :

    The __pragma keyword

    The compiler also supports the Microsoft-specific __pragma keyword, which has the same functionality as the #pragma directive. The difference is, the __pragma keyword is usable inline in a macro definition. The #pragma directive isn’t usable in a macro definition, because the compiler interprets the number sign character (‘#’) in the directive as the stringizing operator (#).

    The following code example demonstrates how the __pragma keyword can be used in a macro. This code is excerpted from the mfcdual.h header in the ACDUAL sample in «Compiler COM Support Samples»:

    The _Pragma preprocessing operator

    _Pragma is similar to the Microsoft-specific __pragma keyword. It was introduced into the C standard in C99, and the C++ standard in C++11. It’s available in C only when you specify the /std:c11 or /std:c17 option. For C++, it’s available in all /std modes, including the default.

    Unlike #pragma , _Pragma allows you to put pragma directives into a macro definition. The string literal should be what you would otherwise put following a #pragma statement. For example:

    Quotation marks and back-slashes should be escaped, as shown above. A pragma string that isn’t recognized is ignored.

    The following code example demonstrates how the _Pragma keyword could be used in an assert-like macro. It creates a pragma directive that suppresses a warning when the condition expression happens to be constant.

    The macro definition uses the do . while(0) idiom for multi-statement macros so that it can be used as though it were one statement. For more information, see C multi-line macro on Stack Overflow. The _Pragma statement in the example only applies to the line of code that follows it.

     

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

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