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


Reply via email to