Introduction
Programming in either C or C++ invariably requires using preprocessor macros at some point. Here’s a collection of macros I...
For further actions, you may consider blocking this person and/or reporting abuse
I was not expecting to find such a high-quality low-level programming post on dev.to.
The STATIC_ASSERT_EXPR is brilliant.
Thanks for sharing.
Thanks. I'm doing my part to raise the bar. The number of low-quality, poorly-written posts is eye-watering. FYI, it's no better on medium.
I agree. Maybe you could post links to your articles to lobste.rs. They would love your post over there.
In any case, I'm now following you. :)
Looking forward to reading your next C articles.
I'd never heard of lobste.rs. I'll give it a look.
I'm currently spending time working on one of my open-source projects rather that writing. In the mean time, there's all my previous articles to read.
I'll be sure to check them out.
Have a great day!
I finally got around to reading about
lobste.rs
. It includes:So I couldn’t post links to my own articles — but you could (if you wanted).
it would be my pleasure, that said, I haven't been invided.
I should work more in public.
This is great content.
I had an issue reproducing RUN_ONCE macro though.
Code exert:
I get the following output
In debug mode, I could see that each MYRUN_ONCE creates a different variable, namely:
run_once_42
run_once_43
.
I was expecting that the same variable would be created and thus MYRUN_ONCE would run only once.
In case it matters, I used a MSVC compiler. Am I getting something wrong here?
You're misunderstanding what
RUN_ONCE
is supposed to do. It's working as intended. The idea is that it runs whatever code you give it once for eachRUN_ONCE
. Neither the macro nor compiler care what that code is, so if you just so happen to give two distinct calls toRUN_ONCE
the same code, it assumes you know what you're doing and runs each bit of code once so it will look like it ran the code twice, but it actually didn't.It's probably better to illustrate using:
The code will correctly print
one
andtwo
once each.As of C11, you can just use
call_once
, but it requires an explicit flag and a separate function for the actual code. My macro just bundles the flag inside itself to be simpler and also allows an arbitrary block of code.Thank you for the fast and precise reply.
Now the flag intention is clearer to me.
I have to admit, this content is great, and I'm also learning new things. Thank you for the support.
Is
STRLITLEN()
designed to work forchar s[10] = "hello"; STRLITLEN(s)
as well asSTRLITLEN("hello")
? If it is supposed to only allow the latter, one could do:As consecutive string literals are concatenated in C, the empty string literal can provide rudimentary type-checking. Surely it can be broken, and more constructs can be added to make it more robust, but the added robustness may not be worth the added complexity.
It's supposed to work for either. Given:
it works just fine because the compiler knows the size. Given:
it will fail because the compiler can’t know the size. The use of
sizeof
in the implementation already correctly handles this.The valid but wrong case this is meant to catch is passing a pointer to it:
Ordinarily, this would compile yet be wrong because
sizeof
would return the size of the pointer — but that’s whyARRAY_SIZE
ensures its argument is an array and not a pointer.I never realized (or I forgot, that's also quite possible) that LINE is the same for all the lines that a macro expands to :o
A macro always expands to a single line. Remember: escaped newlines are eliminated prior to expansion.