answer: you don't
How to properly use macros in C
11–20 of 52 posts
Re: How to properly use macros in C
#12multiple lines: wrap in do { } while (0) - can use a multiline macro like a function call, terminated with ; or ({foo; bar;}) - multiple lines evaluate to 'bar'...
Function calls: - in general anything with side effects could be harmful if evaluated more than once. - But possible to write MIN()/MAX() with single evaluation of 'a' and 'b'. #define MAX(a, b) \ ({typeof(a) _a = (a); typeof(b) _b = (b); _a > _b ? _a : _b;})
And other important things like stringify, variadics, etc...
Re: How to properly use macros in C
#13#2 is referred to as an unsafe macro because of the multiple evaluation of its arguments. In some cases this is fine but it may need to be documented that the macro is unsafe for future users. It is also entirely possible to convert these macros into safe ones if you're willing/able to use GNU C extensions like typeof. The SEI CERT secure C wiki has a good reference for this at [0].
#3 presumes you want to compose functions but I'd suggest that by doing so you are writing bad C. Because of the lack of any type of side-band error reporting (exceptions etc) you must presume that your functions will always return a sane/non-error value. That's not a good assumption even for your own code and definitely not for the C library or any other libs. In addition, this is just another unsafe macro which could be made safe as above.
#4 doesn't explain the solution to the problem it poses which is annoying because it's the most important one IMO. There are a number of ways to make a multi-line macro safe for use in an unbraced expression body. My preferred way is to define the macro with a always false-post check while loop. e.g.
#define MY_NAME_JEF(x) do{ \
const char jef[] = "jef"; \
printf("my name %s, not %s\n", jef, x); \
}while(0)
Note the lack of a trailing semi-colon. This is because we expect the macro to be terminated with its own semi-colon. Stupid example but it gets the point across I suppose.Check out the secure C wiki, it's full of gems which can help you avoid issues with macros, and much more.
[0] https://wiki.sei.cmu.edu/confluence/display/c/PRE31-C.+Avoid...
Re: How to properly use macros in C
#14"We will make you a rich programmer in 3 months", they say.
Re: How to properly use macros in C
#15This isn't wrong but I've got issues with some of the examples, especially the lack of a solution for #2 and #4. #2 is referred to as an unsafe macro because of the multiple evaluation of its arguments. In some cases this is fine but it may need to be documented that the macro is unsafe for future users. It is also entirely possible to convert these macros into safe ones if you're willing/able to use GNU C extensions…
In the early days of C programming, a naming convention was adopted to warn about this. If you wrote a macro that might have multiple evaluation of its arguments, you named it in UPPERCASE as a warning:
#define MIN( a, b ) ( (a)
This practice spread into pretty much all macro definitions. If you defined a macro of any sort, you gave it an uppercase name, even if the macro didn't take any arguments at all and therefore warning about multiple evaluation was moot: #define MAX_SIGNED_SHORT 32767
From there the notion spread into other languages that all constants ought to have UPPER_CASE_NAMES. So this is why you see JavaScript code like: const TEMP_ITEM_LIMIT = 100;
instead of something easier on the eyes like: const tempItemLimit = 100;Re: How to properly use macros in C
#16Re: How to properly use macros in C
#17One strange phenomenon when coding in C is using macros. This is not something which can be seen in other programming languages (other than C++). This is false. Lisp is a language, or rather, a family of languages, where macros play a giant role, and the author does not seem to mention them. But again, Lisps generally have more powerful macros than C does - they allow for arbitrary compile-time computation.
> One strange phenomenon when coding in C is using macros. This is not something which can be seen in other programming languages (other than C++).
Instead of indenting a quote, use:
> The quote.
or if you want italics to set it off more: > *The quote.*Re: How to properly use macros in C
#18One strange phenomenon when coding in C is using macros. This is not something which can be seen in other programming languages (other than C++). This is false. Lisp is a language, or rather, a family of languages, where macros play a giant role, and the author does not seem to mention them. But again, Lisps generally have more powerful macros than C does - they allow for arbitrary compile-time computation.
Re: How to properly use macros in C
#19If you're going to write a long lecture to people, it's helpful to do some Googling to fact-check your own understanding. The claim that macros do not exist in other languages is incorrect. Every sensible assembly language compiler has macros to help the programmer with boilerplate. The claim that multiline macros are a problem is correct. Suggesting that a workaround is to use a naming convention for such macros is…
https://www.youtube.com/watch?v=_ZwiMlyeQNU&t=15s
In short, kids with little to no programming experience teach other disorientated desperate kids with few career opportunities in a country with a primitive economy.
Re: How to properly use macros in C
#20Calling all C preprocessor directives (like #include and #if) "macros" makes me skeptical. Is this usage common?
You are correct, this usage is wrong. They are "preprocessor directives", and macros are only what come after #define.