It seems that the Python C API is not consistent with the const correctness of character arrays. For example, PyImport_ImportFrozenModule accepts a char*
, whereas PyImport_ImportModule accepts a const char*
.
The implication of all this is that in my C++ application that I am writing with an embedded Python interpreter, I sometimes have to cast the string literal that I pass to a Python API call as just a char*
(as opposed to const char*
), and sometimes I don't. For example:
PyObject *os = PyImport_ImportModule("os"); // Works without the const_cast
PyObject *cwd = PyObject_CallMethod(os, const_cast<char*>("getcwd"), NULL); // Accepts char*, not const char*
If I don't do the const_cast<char*>
(or (char*)
) on the string literal, I get a compiler warning about casting string literals to char*
.
Here are my questions:
- Is there an advantage/reason to having some of the functions not take a
const char*
(and/or why would the Python API not be consistent in this)? My understanding is that if the function can take a string literal, it cannot change thechar*
so theconst
modifier would just be reinforcing this. I also believe that theconst
distinction is not as important for C (for which the API was written) than it is in C++ (correct me if I am wrong... my strength is python, not C/C++). Is the lack of "const correctness" of the Python API because it's simply not as important in C? (There is an old thread on the python mailing list from 2000 asking the same question, but it didn't seem to go anywhere and it is implied the reason might be due to some compilers not supportingconst
. Since many functions now haveconst char*
, this doesn't seem to apply anymore) Because my understanding of C++ is limited, I am unsure if I am going about casting string literals properly. The way I see it, I can either one of the following (I am currently doing the first):
// Method 1) Use const_cast<char*> PyImport_ImportFrozenModule(const_cast<char*>("mymodule")); // Method 2) Use (char*) PyImport_ImportFrozenModule((char*) "mymodule"); // Method 3) Use char array char mod[] = "mymodule"; PyImport_ImportFrozenModule(mod);
Which is the best method do use?
Update:
It looks like the Python3 branch is slowly trying to fix the const correctness issue. For example, the PyImport_ImportFrozenModule
function I use as an example above now takes a const char*
in Python 3.4, but there are still functions that take only a char*
, such as PyLong_FromString.