คำถามติดแท็ก c-preprocessor

ตัวประมวลผลแมโครแบบข้อความที่ใช้ก่อนคอมไพล์โปรแกรมภาษา C และ C ++ แท็กนี้ยังสามารถใช้สำหรับคำถามเกี่ยวกับคอมไพเลอร์ / ภาษาอื่น ๆ ที่มาจากหรือที่มีคุณสมบัติเหมือนกันเช่น #directives ใน Objective-C หรือ C #

8
เหตุใดมาโครตัวประมวลผลล่วงหน้าจึงชั่วร้ายและทางเลือกอื่นคืออะไร?
ฉันถามเรื่องนี้มาตลอด แต่ไม่เคยได้รับคำตอบที่ดีเลย ฉันคิดว่าโปรแกรมเมอร์เกือบทุกคนก่อนที่จะเขียน "Hello World" คนแรกเคยพบวลีเช่น "มาโครไม่ควรใช้", "มาโครเป็นสิ่งชั่วร้าย" และอื่น ๆ คำถามของฉันคือ: ทำไม? ด้วย C ++ 11 ใหม่มีทางเลือกใหม่หลังจากผ่านไปหลายปีหรือไม่? ส่วนที่ง่ายคือเกี่ยวกับมาโครเช่น#pragmaซึ่งเป็นแพลตฟอร์มเฉพาะและคอมไพเลอร์เฉพาะและส่วนใหญ่มักมีข้อบกพร่องร้ายแรงเช่น#pragma onceนี้เกิดข้อผิดพลาดได้ง่ายในสถานการณ์สำคัญอย่างน้อย 2 สถานการณ์: ชื่อเดียวกันในเส้นทางที่แตกต่างกันและด้วยการตั้งค่าเครือข่ายและระบบไฟล์บางอย่าง แต่โดยทั่วไปแล้วมาโครและทางเลือกอื่น ๆ ในการใช้งานล่ะ?

7
ทำไมต้องกำหนดมาโครถ้ายังไม่ได้กำหนดไว้
ในฐานรหัส C ของเราฉันเห็นทุกมาโครที่กำหนดด้วยวิธีต่อไปนี้: #ifndef BEEPTRIM_PITCH_RATE_DEGPS #define BEEPTRIM_PITCH_RATE_DEGPS 0.2f #endif #ifndef BEEPTRIM_ROLL_RATE_DEGPS #define BEEPTRIM_ROLL_RATE_DEGPS 0.2f #endif #ifndef FORCETRIMRELEASE_HOLD_TIME_MS #define FORCETRIMRELEASE_HOLD_TIME_MS 1000.0f #endif #ifndef TRIMSYSTEM_SHEARPIN_BREAKINGFORCE_LBS #define TRIMSYSTEM_SHEARPIN_BREAKINGFORCE_LBS 50.0f #endif อะไรคือเหตุผลของการทำการตรวจสอบกำหนดเหล่านี้แทนที่จะเพียงแค่กำหนดมาโคร #define BEEPTRIM_PITCH_RATE_DEGPS 0.2f #define BEEPTRIM_ROLL_RATE_DEGPS 0.2f #define FORCETRIMRELEASE_HOLD_TIME_MS 1000.0f #define TRIMSYSTEM_SHEARPIN_BREAKINGFORCE_LBS 50.0f ฉันไม่พบวิธีปฏิบัตินี้ที่อธิบายไว้ในเว็บ

10
วิธีเปรียบเทียบสตริงใน C เงื่อนไขคำสั่งพรีโปรเซสเซอร์
ฉันต้องทำสิ่งนี้ใน C มันใช้ได้ก็ต่อเมื่อฉันใช้ถ่าน แต่ฉันต้องการสตริง ฉันจะทำเช่นนี้ได้อย่างไร? #define USER "jack" // jack or queen #if USER == "jack" #define USER_VS "queen" #elif USER == "queen" #define USER_VS "jack" #endif

4
จะใช้อาร์กิวเมนต์มาโครเป็นสตริงลิเทอรัลได้อย่างไร
ฉันกำลังพยายามหาวิธีเขียนมาโครที่จะส่งทั้งการแทนค่าตัวอักษรสตริงของชื่อตัวแปรพร้อมกับตัวแปรในฟังก์ชัน ตัวอย่างเช่นให้ฟังก์ชันต่อไปนี้ void do_something(string name, int val) { cout << name << ": " << val << endl; } ฉันต้องการเขียนมาโครดังนั้นฉันจึงสามารถทำได้: int my_val = 5; CALL_DO_SOMETHING(my_val); ซึ่งจะพิมพ์ออกมา: my_val: 5 ฉันลองทำสิ่งต่อไปนี้: #define CALL_DO_SOMETHING(VAR) do_something("VAR", VAR); อย่างไรก็ตามอย่างที่คุณอาจเดาได้ว่า VAR ภายในเครื่องหมายคำพูดจะไม่ถูกแทนที่ แต่จะถูกส่งผ่านเป็นเพียงสตริง "VAR" ดังนั้นฉันต้องการทราบว่ามีวิธีที่จะทำให้อาร์กิวเมนต์มาโครกลายเป็นสตริงลิเทอรัลได้หรือไม่

3
เชื่อมต่อ int กับสตริงโดยใช้ C Preprocessor
ฉันกำลังพยายามหาวิธีเชื่อมสตริง#define'd int กับ a #define' d โดยใช้C Preprocessor คอมไพเลอร์ของฉันคือ GCC 4.1 บน CentOS 5 โซลูชันนี้ควรใช้ได้กับ MinGW ด้วย ฉันต้องการต่อท้ายหมายเลขเวอร์ชันลงในสตริง แต่วิธีเดียวที่ฉันจะทำให้มันใช้งานได้คือการทำสำเนาหมายเลขเวอร์ชันที่กำหนดเป็นสตริง สิ่งที่ใกล้เคียงที่สุดที่ฉันสามารถหาได้คือวิธีการอ้างอาร์กิวเมนต์มาโคร แต่ใช้ไม่ได้กับ#defines สิ่งนี้ไม่ได้ผล #define MAJOR_VER 2 #define MINOR_VER 6 #define MY_FILE "/home/user/.myapp" #MAJOR_VER #MINOR_VER มันไม่ทำงานโดยไม่ต้อง#s ทั้งเพราะค่าจะเป็นตัวเลขและมันจะขยายตัวออกไป"/home/user/.myapp" 2 6ซึ่งไม่ถูกต้องC วิธีนี้ใช้งานได้ แต่ฉันไม่ชอบให้สำเนาของเวอร์ชันกำหนดเพราะฉันต้องการให้เป็นตัวเลขเช่นกัน #define MAJOR_VER 2 #define MINOR_VER 6 #define MAJOR_VER_STR "2" #define MINOR_VER_STR …

19
วิธีง่ายๆในการใช้ตัวแปรประเภท enum เป็นสตริงใน C?
นี่คือสิ่งที่ฉันพยายามทำ: typedef enum { ONE, TWO, THREE } Numbers; ฉันกำลังพยายามเขียนฟังก์ชันที่จะทำกรณีสวิตช์คล้ายกับต่อไปนี้: char num_str[10]; int process_numbers_str(Numbers num) { switch(num) { case ONE: case TWO: case THREE: { strcpy(num_str, num); //some way to get the symbolic constant name in here? } break; default: return 0; //no match return 1; } แทนที่จะกำหนดทุกกรณีมีวิธีตั้งค่าโดยใช้ตัวแปร enum เหมือนที่ฉันพยายามทำข้างต้นหรือไม่?

13
แอปพลิเคชันของตัวดำเนินการประมวลผล ## preprocessor และ gotchas ที่ต้องพิจารณามีอะไรบ้าง?
ดังที่ได้กล่าวไว้ในคำถามก่อนหน้านี้หลายข้อฉันกำลังทำงานผ่าน K&R และกำลังอยู่ในพรีโปรเซสเซอร์ สิ่งที่น่าสนใจอีกอย่างหนึ่ง - สิ่งที่ฉันไม่เคยรู้มาก่อนจากการพยายามเรียนรู้ C - ก่อนหน้านี้คือ##ตัวดำเนินการก่อนโปรเซสเซอร์ ตาม K&R: ตัวดำเนินการตัวประมวลผลก่อน## จัดเตรียมวิธีการต่ออาร์กิวเมนต์ที่แท้จริงระหว่างการขยายมาโคร หากพารามิเตอร์ในข้อความแทนที่อยู่ติดกับ a ##พารามิเตอร์จะถูกแทนที่ด้วยอาร์กิวเมนต์จริง ##และช่องว่างรอบ ๆ จะถูกลบออกและผลลัพธ์จะถูกสแกนใหม่ ตัวอย่างเช่นแมโครpaste เชื่อมสองอาร์กิวเมนต์: #define paste(front, back) front ## back เพื่อสร้างโทเค็นpaste(name, 1) name1 ทำไมคนถึงใช้สิ่งนี้ในโลกแห่งความเป็นจริง ตัวอย่างการใช้งานจริงมีอะไรบ้างและมีข้อควรพิจารณาหรือไม่?



5
นับจำนวนไฟล์ซอร์สโดยใช้มาโครหรือไม่
เป็นไปได้หรือไม่ที่จะใช้ตัวประมวลผลล่วงหน้า C / C ++ เพื่อนับบรรทัดภายในไฟล์ต้นฉบับไปเป็นมาโครหรือค่าคอมไพล์เวลาที่รวบรวมได้ เช่นฉันสามารถแทนที่MAGIC1, MAGIC2และMAGIC3ในต่อไปนี้และได้รับค่า 4 อย่างใดเมื่อใช้MAGIC3? MAGIC1 // can be placed wherever you like before the relevant // lines - either right before them, or in global scope etc. foo(); MAGIC2 bar(); MAGIC2 baz(); MAGIC2 quux(); MAGIC2 // ... possibly a bunch of code here; not …
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.