Использование #pragma в C

Каковы некоторые применения #pragma в C с примерами?

Ответ 1

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

Подробнее см. msdn.

Ответ 2

#pragma используется для того, чтобы сделать что-то специфичное для реализации в C, то есть быть прагматичным для текущего контекста, а не идеологически догматичным.

То, что я регулярно использую, это #pragma pack(1), где я пытаюсь выжать больше из своего пространства памяти на встроенные решения, с массивами структур, которые в противном случае заканчивались 8-байтовым выравниванием.

Жаль, что у нас еще нет #dogma. Это было бы весело;)

Ответ 3

Обычно я старался избегать использования #pragmas, если это возможно, поскольку они чрезвычайно зависимы от компилятора и не переносятся. Если вы хотите использовать их в переносном режиме, вам придется окружать каждую прагму парой # if/# endif. GCC препятствует использованию прагм и действительно поддерживает некоторые из них для совместимости с другими компиляторами; GCC имеет другие способы делать то же самое, что другие компиляторы используют прагмы для.

Например, здесь вы должны убедиться, что структура упакована плотно (т.е. нет прокладки между элементами) в MSVC:

#pragma pack(push, 1)
struct PackedStructure
{
  char a;
  int b;
  short c;
};
#pragma pack(pop)
// sizeof(PackedStructure) == 7

Вот как вы сделали бы то же самое в GCC:

struct PackedStructure __attribute__((__packed__))
{
  char a;
  int b;
  short c;
};
// sizeof(PackedStructure == 7)

Код GCC более переносимый, потому что если вы хотите скомпилировать его с компилятором, отличным от GCC, все, что вам нужно сделать, это

#define __attribute__(x)

Если вы хотите портировать код MSVC, вы должны окружить каждую прагму парой # if/# endif. Не очень.

Ответ 4

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

Альтернативой является использование защитных ограждений (например, #ifndef MY_FILE #define MYFILE ... #endif)

Ответ 5

то, что я чувствую #pragma, является директивой, где, если вы хотите, чтобы код был специфичным для местоположения. Укажите ситуацию, когда вы хотите, чтобы счетчик программ читал с определенного адреса, где был записан ISR, тогда вы можете указать ISR на это местоположение с помощью #pragma vector=ADC12_VECTOR и followd с помощью имени прерываний и его описания

Ответ 6

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

#pragma code BANK1
#pragma data BANK2

#pragma INT3 TimerHandler

Ответ 7

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

Он имеет два типа: #pragma startup, #pragma exit и #pragma warn.

#pragma startup позволяет нам указывать функции, вызываемые при запуске программы.

#pragma exit позволяет нам указывать функции, вызванные выходом программы.

#pragma warn указывает компьютеру подавить любое предупреждение или нет.

Для управления компилятором можно использовать многие другие стили #pragma.

Ответ 8

Подводя итог, #pragma сообщает компилятору, что он делает. Вот несколько способов использования:

  • #pragma может использоваться для игнорирования предупреждений компилятора. Например, чтобы заставить GCC заткнуться о неявных декларациях функций, вы можете написать:

    #pragma GCC diagnostic ignored "-Wimplicit-function-declaration"
    

    Более старая версия libportable делает это портативно.

  • #pragma once, когда он написан в верхней части файла заголовка, приведет к тому, что указанный файл заголовка будет включен один раз. libportable проверяет для поддержки pragma после поддержки.

Ответ 9

#pragma startup - это директива, которая используется для вызова функции перед основной функцией и для вызова другой функции после основной функции, например

#pragma startup func1
#pragma exit func2

Здесь func1 выполняется до main и func2 запускается впоследствии.

ПРИМЕЧАНИЕ. Этот код работает только в компиляторе Turbo-C. Чтобы достичь этой функциональности в GCC, вы можете объявить func1 и func2 следующим образом:

void __attribute__((constructor)) func1();
void __attribute__((destructor)) func2();

Ответ 10

Все ответы выше дают приятные объяснения #pragma, но я хотел добавить небольшой пример

Я просто хочу объяснить simple OpenMP example, которые демонстрируют некоторые применения #pragma для выполнения своей работы

OpenMp briefly - это реализация для многоплатформенной общей памяти параллельное программирование (тогда мы можем сказать это machine-specific или operating-system-specific)

отпустите в примере

#include <stdio.h>
#include <omp.h>// compile with: /openmp

int main() {
   #pragma omp parallel num_threads(4)
   {
      int i = omp_get_thread_num();
      printf_s("Hello from thread %d\n", i);
   }
}

вывод

Hello from thread 0
Hello from thread 1
Hello from thread 2
Hello from thread 3

Note that the order of output can vary on different machines.

теперь позвольте мне сказать вам, что #pragma сделал...

он сообщает ОС, чтобы запустить некоторый блок кода на 4 потоках

Это всего лишь один из many many applications, который вы можете сделать с маленьким #pragma

извините за внешний образец OpenMP