[Python-Dev] Baffled by PyArg_ParseTupleAndKeywords modification

Bengt Richter bokr at oz.net
Sat Feb 11 03:02:10 CET 2006

On Fri, 10 Feb 2006 17:53:39 +0100, Thomas Wouters <thomas at xs4all.net> wrote:

>On Fri, Feb 10, 2006 at 11:30:30AM -0500, Jeremy Hylton wrote:
>> On 2/10/06, Guido van Rossum <guido at python.org> wrote:
>> > OMG. Are we now adding 'const' modifiers to random places? I thought
>> > "const propagation hell" was a place we were happily avoiding by not
>> > falling for that meme. What changed?
>> I added some const to several API functions that take char* but
>> typically called by passing string literals.  In C++, a string literal
>> is a const char* so you need to add a const_cast<> to every call site,
>> which is incredibly cumbersome.  After some discussion on python-dev,
>> I made changes to a small set of API functions and chased the
>> const-ness the rest of the way, as you would expect.  There was
>> nothing random about the places const was added.
>> I admit that I'm also puzzled by Jack's specific question.  I don't
>> understand why an array passed to PyArg_ParseTupleAndKeywords() would
>> need to be declared as const.  I observed the problem in my initial
>> changes but didn't think very hard about the cause of the problem. 
>> Perhaps someone with better C/C++ standards chops can explain.
>Well, it's counter-intuitive, but a direct result of how pointer equivalence
>is defined in C. I'm rusty in this part, so I will get some terminology
>wrong, but IIRC, a variable A is of an equivalent type of variable B if they
>hold the same type of data. So, a 'const char *' is equivalent to a 'char *'
>because they both hold the memory of a 'char'. But a 'const char**' (or
>'const *char[]') is not equivalent to a 'char **' (or 'char *[]') because
>the first holds the address of a 'const char *', and the second the address
>of a 'char *'. A 'char * const *' is equivalent to a 'char **' though.
>As I said, I got some of the terminology wrong, but the end result is
>exactly that: a 'const char **' is not equivalent to a 'char **', even
>though a 'const char *' is equivalent to a 'char *'. Equivalence, in this
>case, means 'can be automatically downcasted'. Peter v/d Linden explains
>this quite well in "Expert C Programming" (aka 'Deep C Secrets'), but
>unfortunately I'm working from home and I left my copy at a coworkers' desk.
Would it make sense to use a typedef for readability's sake? E.g.,

    typedef const char * p_text_literal;

and then use

    p_text_literal, const p_text_literal *

in the signature, for read-only access to the data? (hope I got that right).

(also testing whether I have been redirected to /dev/null ;-)

Bengt Richter

More information about the Python-Dev mailing list