[petsc-dev] Preprocessor hell: #define VecType
Karl Rupp
rupp at mcs.anl.gov
Sun Sep 30 08:46:15 CDT 2012
Hi,
>>> ^^^ Note that this const is superfluous.
>> Why is it superfluous? Isn't the second argument type const char* const this way?
>>
>> It's superfluous for the same reason we don't "set" by passing "const PetscInt". The const is irrelevant to the caller. All it means is that the implementation doesn't change the *its* copy (pass by value) and even that isn't type checked with respect to the public declaration. It's just clutter and suggests that the person who wrote it doesn't understand types.
>
> Which clearly I don't :-(
>
> So do we just go with typedef const char* VecType and then all signatures are VecType?
yes, Jed is absolutely right on that. The important thing to keep in
mind here is that typedef is atomic, i.e. it is not a 'string
replacement' as opposed to what the C preprocessor does.
Example:
#define VecType char*
int Set(const VecType)
expands to
int Set(const char*)
However, with
typedef const char* VecType
int Set(const VecType)
there is no immediate string replacement, i.e. it is NOT the same as
int Set(const const char*)
with the compiler ignoring one of the const keywords. Instead, denoting
the precedence using brackets, the type passed to the Set() is
const {const char*}
which is a const copy to a const char*. Now, as 'const char*' is copied
when passed to the function anyways, the first 'const' is superfluous as
Jed pointed out. As a consequence, we can simply use
Set(VecType);
Get(VecType*);
which is pretty much the standard prototype for any pair of
Getter/Setter and also the way arguments of type PetscInt are handled.
In conclusion, we have not only eliminated the preprocessor magic, we
are also able to provide a cleaned-up interface for XYZSetType() and
XYZGetType(). Thanks, Barry, for making the decision in favor of a
typedef :-)
Best regards,
Karli
More information about the petsc-dev
mailing list