ใช้อะไรบ้าง#pragma
ใน C พร้อมตัวอย่าง
ใช้อะไรบ้าง#pragma
ใน C พร้อมตัวอย่าง
คำตอบ:
#pragma
มีไว้สำหรับคำสั่งคอมไพเลอร์ที่เฉพาะเครื่องหรือเฉพาะระบบปฏิบัติการกล่าวคือบอกให้คอมไพเลอร์ทำบางอย่างตั้งค่าตัวเลือกดำเนินการบางอย่างแทนที่ค่าเริ่มต้นบางอย่าง ฯลฯ ที่อาจใช้กับเครื่องและปฏิบัติการทั้งหมดหรือไม่ก็ได้ ระบบ
ดูmsdnสำหรับข้อมูลเพิ่มเติม
#pragma
ถูกใช้เพื่อทำบางสิ่งบางอย่างที่ใช้เฉพาะใน C นั่นคือเป็นแนวทางปฏิบัติสำหรับบริบทปัจจุบันมากกว่าที่จะดันทุรังตามอุดมคติ
สิ่งที่ฉันใช้เป็นประจำคือ#pragma pack(1)
จุดที่ฉันพยายามบีบพื้นที่หน่วยความจำของฉันให้มากขึ้นบนโซลูชันแบบฝังโดยมีอาร์เรย์ของโครงสร้างที่จะลงเอยด้วยการจัดตำแหน่ง 8 ไบต์
สงสารเรา#dogma
ยังไม่มี น่าจะสนุกนะ;)
pragma(1)
เร่งความเร็วด้วยเหรอ ดูstackoverflow.com/questions/3318410/…
โดยทั่วไปฉันจะพยายามหลีกเลี่ยงการใช้ #pragmas ถ้าเป็นไปได้เนื่องจากมันขึ้นอยู่กับคอมไพเลอร์และไม่พกพา หากคุณต้องการใช้แบบพกพาคุณจะต้องล้อมรอบ pragma ทุกตัวด้วย a #if
/ #endif
pair GCC ไม่สนับสนุนการใช้ pragmas และรองรับเฉพาะบางส่วนเท่านั้นสำหรับความเข้ากันได้กับคอมไพเลอร์อื่น ๆ GCC มีวิธีอื่น ๆ ในการทำสิ่งเดียวกันกับที่คอมไพเลอร์อื่น ๆ ใช้ pragmas
ตัวอย่างเช่นต่อไปนี้เป็นวิธีที่คุณจะมั่นใจได้ว่าโครงสร้างถูกบรรจุอย่างแน่นหนา (เช่นไม่มีช่องว่างระหว่างสมาชิก) ใน 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 คุณต้องล้อมรอบ pragma แต่ละตัวด้วย a #if
/ #endif
pair ไม่สวย.
struct __attribute__((__packed__)) PackedStructure
hack
เมื่อพบ pragma ที่ไม่รู้จักเหมือนที่เคยทำเมื่อนานมาแล้ว - ดู#pragma
และ GCCฯลฯ )
การวาง#pragma once
ไว้ที่ด้านบนสุดของไฟล์ส่วนหัวจะช่วยให้มั่นใจได้ว่าไฟล์จะถูกรวมไว้เพียงครั้งเดียว โปรดทราบว่า#pragma once
ไม่ใช่ C99 มาตรฐาน แต่สนับสนุนโดยคอมไพเลอร์สมัยใหม่ส่วนใหญ่
อีกทางเลือกหนึ่งคือการใช้รวมถึงยาม (เช่น#ifndef MY_FILE #define MY_FILE ... #endif /* MY_FILE */
)
สิ่งที่ฉันรู้สึกว่าเป็น#pragma
คำสั่งที่หากคุณต้องการให้รหัสระบุตำแหน่งโดยเฉพาะพูดถึงสถานการณ์ที่คุณต้องการให้ตัวนับโปรแกรมอ่านจากที่อยู่เฉพาะที่เขียน ISR จากนั้นคุณสามารถระบุ ISR ที่ตำแหน่งนั้นโดยใช้#pragma vector=ADC12_VECTOR
และตามด้วย ขัดจังหวะชื่อ rotines และคำอธิบาย
คำแนะนำที่ดีที่สุดของฉันคือดูเอกสารของคอมไพเลอร์ของคุณเนื่องจาก pragmas เป็นไปตามข้อกำหนดเฉพาะการใช้งาน ตัวอย่างเช่นในโครงการฝังตัวฉันได้ใช้มันเพื่อค้นหารหัสและข้อมูลในส่วนต่างๆหรือประกาศตัวจัดการขัดจังหวะ เช่น:
#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 เมื่อสนับสนุน
#pragma
คำสั่งยังคงอยู่ในขั้นตอนก่อนการประมวลผล ไม่เหมือน#include
และ#define
.