For projects that will never have more than ~1 million LOC it's probably fine. Less than ~100K, definitely preferable.
Basically just wondering if anyone has first hand experience using this kind of thing on a large project.
Sometimes you do want to debug a release build because the optimizations have gone wrong, though. In that case, it's helpful if release builds build quickly, and especially if they rebuild quickly as you turn various sub-optimization flags on and off.
Unfortunately there are always tradeoffs using macros for something like that, you either end up evaluating the parameters more than once or you have to introduce variables in the macro that may shadow existing variables. Some compilers have extensions to help with that: https://gcc.gnu.org/onlinedocs/gcc/Statement-Exprs.html
You certainly don’t have to introduce the risk of shadowing existing variables. You just use the standard
#define MACRO(x) \
do { \
/* Define whatever variables you like */ \
/* Do things... */ \
} while (0)Second, you still risk shadowing existing variables, even if you make an effort to use "unlikely" names for the locals such as "___my_macro_secret_variable_1", if the macro might be used in one of its own arguments. For example MACRO(MACRO(x)).
If that sounds unlikely, consider MAX(a,MAX(b,c)), which is likely to happen eventually, if your codebase uses such macros or if they are part of a library.
#define maxint(a,b) \
({int _a = (a), _b = (b); _a > _b ? _a : _b; })
>Note that introducing variable declarations (as we do in maxint) can cause variable shadowing [...] this example using maxint will not [produce correct results]: int _a = 1, _b = 2, c;
c = maxint (_a, _b); fn sqr<T: Copy + Mul>(x: T) -> T::Output {
x * x
}Don't use a macro where a function will do.
I hope I get to use C2x* before I retire.
*postmodern C?
AFAIK the only non-supported C99 features in the C compiler are VLAs (optional since C11 anyway), and type-generic macros (those would be good to have though).
Of course it would be nice if Microsoft gave the C compiler a bit more love, especially since it's much less work keeping a C compiler uptodate than a C++ compiler, but at least we got "most of C99".
Although inline was added in C99, it was already an extremely widely supported extension in mainstream compilers, even since the C89 days, when we just called it "ANSI C".
MSVC has supported inline for a long time, long before it started supporting other C99 features.
I could understand the concern if it was about portability to other target platforms, or keeping the option of doing so. But in that case, the public standard your current target supports is irrelevant.
So they add a feature not supported by MSVC and don't learn that it doesn't work until someone else tries to build on Windows.
If you choose to use features based on whether they work or not, you don't need to choose a standard at all. But that loses you all of the guarantees a standard provides.
Slightly off-topic, but it's important to point out that in modern C, implementing such a function as a macro is always a mistake. You'd do it as an inline function.
Macros in modern C should only be used for code generation (for DRY). If the language supports doing it without a macro, then do it without a macro.