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