ใช้อะไรบ้าง#pragmaใน C พร้อมตัวอย่าง
ใช้อะไรบ้าง#pragmaใน C พร้อมตัวอย่าง
คำตอบ:
#pragma มีไว้สำหรับคำสั่งคอมไพเลอร์ที่เฉพาะเครื่องหรือเฉพาะระบบปฏิบัติการกล่าวคือบอกให้คอมไพเลอร์ทำบางอย่างตั้งค่าตัวเลือกดำเนินการบางอย่างแทนที่ค่าเริ่มต้นบางอย่าง ฯลฯ ที่อาจใช้กับเครื่องและปฏิบัติการทั้งหมดหรือไม่ก็ได้ ระบบ
ดูmsdnสำหรับข้อมูลเพิ่มเติม
#pragma ถูกใช้เพื่อทำบางสิ่งบางอย่างที่ใช้เฉพาะใน C นั่นคือเป็นแนวทางปฏิบัติสำหรับบริบทปัจจุบันมากกว่าที่จะดันทุรังตามอุดมคติ
สิ่งที่ฉันใช้เป็นประจำคือ#pragma pack(1)จุดที่ฉันพยายามบีบพื้นที่หน่วยความจำของฉันให้มากขึ้นบนโซลูชันแบบฝังโดยมีอาร์เรย์ของโครงสร้างที่จะลงเอยด้วยการจัดตำแหน่ง 8 ไบต์
สงสารเรา#dogmaยังไม่มี น่าจะสนุกนะ;)
pragma(1)เร่งความเร็วด้วยเหรอ ดูstackoverflow.com/questions/3318410/…
โดยทั่วไปฉันจะพยายามหลีกเลี่ยงการใช้ #pragmas ถ้าเป็นไปได้เนื่องจากมันขึ้นอยู่กับคอมไพเลอร์และไม่พกพา หากคุณต้องการใช้แบบพกพาคุณจะต้องล้อมรอบ pragma ทุกตัวด้วย a #if/ #endifpair 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/ #endifpair ไม่สวย.
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.