Каковы некоторые применения #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