About Me
Welcome to my blog! This is where I collect my observations and notes on programming and technology. The main subjects range from implementation details to broader ideas about programming.
Main Topics
- Engineering Projects: Exploring implementation details and how technical systems work.
- C/C++: Notes on language features and programming techniques.
- The Programmer’s Perspective: Ideas about developing a career and a way of thinking as a programmer.
For more, visit the categories page.
Contact
If you have questions or would like to discuss something, please get in touch through the About page.
Thank you for reading and for your support. I hope these notes help you on your own technical journey!
Commenting Multiline Macros: A Mistake Worth Recognizing
A Correct Example
1 |
|
Output:
1 | use some_macro: 6 |
The preprocessed file contains:
1 | # 6 "test1.c" |
The familiar rule is visible here: a backslash immediately followed by a newline continues the macro definition onto the next physical line.
What Happens If We Add This Comment?
1 |
|
The compiler reports:
1 | test2.c:4:13: error: expected ‘)’ before ‘+’ token |
Inspect the preprocessed file:
1 | # 4 "test2.c" |
The #define has defined an empty macro. Its expansion leaves an empty argument in the printf call, while the code that originally followed the comment remains outside the macro definition.
A line such as //这个宏是做加法—meaning “this macro performs addition”—has no trailing backslash in this example. Consequently, the macro definition ends at that physical newline. The following expression is no longer part of the replacement list:
1 | ((x) + |
The compiler cannot interpret this fragment as a valid declaration at that position, so it reports an error.
What If We Continue the Comment Line Too?
1 |
|
Adding a backslash after the comment looks like the obvious fix. Surely that should work? Here is the compiler’s answer:
1 | test3.c:9:56: error: expected expression before ‘)’ token |
This is a particularly difficult bug to diagnose: the error is reported where the macro is invoked, rather than where the faulty definition appears. My own experience with it is described below.
A single-line comment is still wrong here. Backslash-newline splicing first joins the physical lines into one logical line. Placing a // comment in the middle effectively produces:
1 | #define some_macro(x, y) //这个宏是做加法 ((x) + (y) ) |
What we wanted was:
1 | #define some_macro(x, y) ((x) + (y) ) |
In the first version, the rest of the macro’s code becomes part of the comment. The preprocessed output confirms this:
1 | # 7 "test3.c" |
Everything after the comment marker has disappeared with the comment.
The Correct Comment Form
1 |
|
This version works. A block comment ends at */, so the continued macro body after it is retained. The same preprocessing order explains both the failure above and this correction.
How I Made This Mistake in a Project
The project used many macros to shorten repetitive code. After reading page after page of multiline macro definitions, I inserted a comment into this one:
1 | #define INSTPAT(pattern, ...) do { \ |
I even remembered to put a backslash after the comment. Nevertheless, the compiler’s reported location was not where I had introduced the error. It pointed to a macro invocation and produced diagnostics about other code that looked obviously correct. I spent an afternoon and an evening tracing the problem before recognizing what the single-line comment had done.
If you like this blog or find it useful for you, you are welcome to comment on it. You are also welcome to share this blog, so that more people can participate in it. All the images used in the blog are my original works or AI works, if you want to take it,don't hesitate. Thank you !