Ulrich said:
Skarmander wrote:
I hope I misunderstand you here, or are you really saying that macro
functions are part of C culture and therefore you are using them even if
there are better alternatives?
No. I'm saying people in general do this, and that they will also
dispute what's "better".
Anyhow, I never found a compiler that did not understand inline (yes, a few
of them needed __inline or __inline__, a case where the preprocessor can
be made good use of). I admit I don't do much programming on legacy
systems though, so it might be possible that such compilers still exist.
None of the compilers I did and do C with claimed C99 conformance btw,
except for newer gccs perhaps.
The problem I see is that people will reach for the preprocessor first,
and inline (or __inline or __inline__) second, precisely because
everyone knows and loves the preprocessor. This is especially tempting
for those oneliners you *could* turn into a proper function, but don't.
Projects that make heavy use of inlined functions typically do approach
the problem systematically and use a #define (yes!) with INLINE
expanding to whatever keyword is appropriate. (See? Another valid use of
the preprocessor.
But most people won't bother with the set-up.
Another common use of the preprocessor is for "generic" functions. You know:
#define max(x, y) ((x) > (y) ? (x) : (y))
Much clearer than writing that silly ternary operator all the time, and
see how it works regardless of type?
Incidentally, this particular macro cost me quite a bit of time to track
down in the header files supplied with Visual Studio, as it caused
compilation of a C++ program that used the max function in the standard
library to fail. I finally found the #define, and the NOMINMAX define
that would turn it off. Joy. (I'm sure they've fixed this problem by
now, but I haven't checked.)
AFAIK, C has another big problem in that aspect, a constant does not
constitute an 'integral constant expression', i.e. it can't be used
specify the size of an array. I'm rather sure of this for C89, not so sure
about C99.
And exactly because of this sort of confusion, people will prefer to use
a #define where at least they know they'll get a constant number, not
a readonly-but-not-really-a-constant variable they have to declare
"extern" and other bothersome constructs. "const" is a bit of a misnomer.
Hmm, maybe this is the reason you attribute 'macros are evil' to C++ since
in C++ 'inline' is part of the language and constants can be used to
declare arrays, so two possible reasons that you need them are gone.
It did start with C++, when people observed that these constructs made
the language capable of doing a common thing directly, rather than
needing the preprocessor as a crutch. I'm sure quite a few people still
don't get what the fuss is about.
Those are the best present solution for something that should be a proper
part of the language. It doesn't justify using macros in places where a
better alternative exists.
<snip>
Yes, the keyword in all of these things is "where a better alternative
exists". Keep in mind that "better" is also subjective, as per elsewhere
in this thread. If it's very important to you that everything happens at
compile time, for example, you may be required to use macros for things
that could very well be done in the language itself, but that you're
just not willing to pay the cost for.
The include guards problem is part of C's barebones approach to
dependency management, in that it has none, and expects you to pick up
the slack. I'm sure many people actually like *that*, too.
S.