มาโครเป็นข้อความคัดลอก / วางที่ตัวประมวลผลล่วงหน้าจะใส่ในรหัสของแท้ ผู้เขียนของแมโครหวังว่าการแทนที่จะสร้างรหัสที่ถูกต้อง
มีสาม "เคล็ดลับที่ดี" ที่จะประสบความสำเร็จในการที่:
ช่วยให้แมโครทำงานเหมือนรหัสของแท้
รหัสปกติมักจะสิ้นสุดด้วยเซมิโคลอน หากรหัสการดูของผู้ใช้ไม่จำเป็นต้องใช้ ...
doSomething(1) ;
DO_SOMETHING_ELSE(2) // <== Hey? What's this?
doSomethingElseAgain(3) ;
นี่หมายความว่าผู้ใช้คาดหวังว่าคอมไพเลอร์จะสร้างข้อผิดพลาดหากเซมิโคลอนไม่อยู่
แต่เหตุผลที่ดีที่แท้จริงคือในบางครั้งผู้เขียนแมโครอาจจำเป็นต้องแทนที่แมโครด้วยฟังก์ชันของแท้ ดังนั้นมาโครควรจะเป็นจริงทำตัวเหมือนหนึ่ง
ดังนั้นเราควรมีมาโครที่ต้องการเซมิโคลอน
สร้างรหัสที่ถูกต้อง
ดังที่แสดงในคำตอบของ jfm3 บางครั้งแมโครมีมากกว่าหนึ่งคำสั่ง และถ้ามีการใช้แมโครภายในคำสั่ง if ถ้านี่จะเป็นปัญหา:
if(bIsOk)
MY_MACRO(42) ;
มาโครนี้สามารถขยายเป็น:
#define MY_MACRO(x) f(x) ; g(x)
if(bIsOk)
f(42) ; g(42) ; // was MY_MACRO(42) ;
g
ฟังก์ชั่นจะถูกดำเนินการโดยไม่คำนึงถึงความคุ้มค่าของbIsOk
ฟังก์ชั่นจะถูกดำเนินการโดยไม่คำนึงถึงความคุ้มค่าของ
ซึ่งหมายความว่าเราต้องเพิ่มขอบเขตให้กับแมโคร:
#define MY_MACRO(x) { f(x) ; g(x) ; }
if(bIsOk)
{ f(42) ; g(42) ; } ; // was MY_MACRO(42) ;
สร้างรหัสที่ถูกต้อง 2
หากแมโครเป็นสิ่งที่ต้องการ:
#define MY_MACRO(x) int i = x + 1 ; f(i) ;
เราอาจมีปัญหาอื่นในรหัสต่อไปนี้:
void doSomething()
{
int i = 25 ;
MY_MACRO(32) ;
}
เพราะมันจะขยายเป็น:
void doSomething()
{
int i = 25 ;
int i = 32 + 1 ; f(i) ; ; // was MY_MACRO(32) ;
}
แน่นอนว่ารหัสนี้จะไม่ได้รับการคอมไพล์ ดังนั้นอีกครั้งโซลูชันกำลังใช้ขอบเขต:
#define MY_MACRO(x) { int i = x + 1 ; f(i) ; }
void doSomething()
{
int i = 25 ;
{ int i = 32 + 1 ; f(i) ; } ; // was MY_MACRO(32) ;
}
รหัสทำงานอย่างถูกต้องอีกครั้ง
การรวมเอฟเฟ็กต์ของขอบเขตแบบกึ่งโคลอน +
มีสำนวน C / C ++ หนึ่งอันที่สร้างเอฟเฟกต์นี้: ลูป do / while:
do
{
// code
}
while(false) ;
สิ่งที่ต้องทำ / ในขณะที่สามารถสร้างขอบเขตดังนั้น encapsulating โค้ดของแมโครและต้องการเซมิโคลอนในท้ายที่สุดจึงขยายเป็นโค้ดที่ต้องการ
โบนัสหรือไม่
คอมไพเลอร์ C ++ จะปรับให้เหมาะที่สุดกับ do / while loop เนื่องจากความจริงแล้วโพสต์เงื่อนไขนั้นเป็นเท็จนั้นรู้จักกันในเวลารวบรวม ซึ่งหมายความว่าแมโครเช่น:
#define MY_MACRO(x) \
do \
{ \
const int i = x + 1 ; \
f(i) ; g(i) ; \
} \
while(false)
void doSomething(bool bIsOk)
{
int i = 25 ;
if(bIsOk)
MY_MACRO(42) ;
// Etc.
}
จะขยายอย่างถูกต้องเป็น
void doSomething(bool bIsOk)
{
int i = 25 ;
if(bIsOk)
do
{
const int i = 42 + 1 ; // was MY_MACRO(42) ;
f(i) ; g(i) ;
}
while(false) ;
// Etc.
}
และรวบรวมและปรับให้เหมาะสมเป็น
void doSomething(bool bIsOk)
{
int i = 25 ;
if(bIsOk)
{
f(43) ; g(43) ;
}
// Etc.
}
void
ประเภทที่สิ้นสุด ... เหมือน((void) 0)