Які існують приклади використання #pragma
в С на прикладі?
Які існують приклади використання #pragma
в С на прикладі?
Відповіді:
#pragma
призначений для директив компілятора, які є специфічними для машини або для операційної системи, тобто він повідомляє компілятору щось зробити, встановити певну опцію, вжити певних дій, змінити дефолт за умовчанням тощо. систем.
Див. Msdn для отримання додаткової інформації.
#pragma
використовується для того, щоб зробити щось, що стосується реалізації C, тобто бути прагматичним для сучасного контексту, а не ідеологічно догматичним.
Я регулярно використовую те, #pragma pack(1)
де я намагаюся витіснити більше місця з пам’яті на вбудованих рішеннях, з масивами структур, які в іншому випадку закінчуються 8-байтним вирівнюванням.
Шкода, що у нас ще #dogma
немає. Це було б весело;)
pragma(1)
підвищує швидкість? Див stackoverflow.com/questions/3318410 / ...
Я, як правило, намагаюся уникати використання #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
парами. Не дуже.
struct __attribute__((__packed__)) PackedStructure
hack
коли він стикається з прагмою, яку він не розпізнає, як це було колись дуже-дуже давно - див. #pragma
І GCC тощо)
Введення #pragma once
в верхній частині файлу заголовка буде переконатися , що він включений тільки один раз. Зауважте, що #pragma once
це не стандартний C99, але підтримується більшістю сучасних компіляторів.
Альтернативою є використання включених охоронців (наприклад #ifndef MY_FILE #define MY_FILE ... #endif /* MY_FILE */
)
що я відчуваю - #pragma
це директива, де, якщо ви хочете, щоб код визначався місцеположенням. скажімо, ситуація, коли ви хочете, щоб лічильник програм зчитувався з конкретної адреси, де написано ISR, тоді ви можете вказати ISR в цьому місці за допомогою #pragma vector=ADC12_VECTOR
і далі перервати назву підпрограми та її опис
Моя найкраща порада - переглянути документацію вашого компілятора, оскільки прагми за визначенням залежать від конкретної реалізації. Наприклад, у вбудованих проектах я використовував їх для пошуку коду та даних у різних розділах або для оголошення обробників переривань. тобто:
#pragma code BANK1
#pragma data BANK2
#pragma INT3 TimerHandler
Всі відповіді вище дають хороші пояснення, #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
Це директива препроцесора, яку можна використовувати для включення або вимкнення певних функцій.
Він буває двох видів #pragma startup
, #pragma exit
і #pragma warn
.
#pragma startup
дозволяє вказати функції, закликані при запуску програми.
#pragma exit
дозволяє вказати функції, викликані при виході з програми.
#pragma warn
повідомляє комп’ютеру придушити будь-яке попередження чи ні.
#pragma
Для управління компілятором можна використовувати багато інших стилів.
#pragma startup
- це директива, яка використовується для виклику функції перед основною функцією та для виклику іншої функції після основної функції, наприклад
#pragma startup func1
#pragma exit func2
Тут func1
працює раніше main
і func2
біжить після цього.
ПРИМІТКА. Цей код працює лише в компіляторі Turbo-C. Щоб досягти цієї функціональності в GCC, ви можете заявити func1
і func2
сподобатися так:
void __attribute__((constructor)) func1();
void __attribute__((destructor)) func2();
Підсумовуючи це, #pragma
каже компілятору робити речі. Ось кілька способів, якими я користуюся:
#pragma
може використовуватися для ігнорування попереджень компілятора. Наприклад, щоб GCC закрився щодо неявних функцій оголошень, ви можете написати:
#pragma GCC diagnostic ignored "-Wimplicit-function-declaration"
Старіша версія libportable
робить це портативно .
#pragma once
, коли написано вгорі файлу заголовка, призведе до того, що зазначений файл заголовка буде включений один раз. libportable
перевірка на підтримку прагми.
#pragma
Директива переживає етап попередньої обробки. На відміну від#include
і#define
.