Commit 6436c7d2 authored by Yury V. Zaytsev's avatar Yury V. Zaytsev

Prefer the use of C++ style pointer declarations (char *c -> char* c)

parent fa7f2832
...@@ -129,7 +129,7 @@ Here is a first start for the Queue class:: ...@@ -129,7 +129,7 @@ Here is a first start for the Queue class::
cimport cqueue cimport cqueue
cdef class Queue: cdef class Queue:
cdef cqueue.Queue *_c_queue cdef cqueue.Queue* _c_queue
def __cinit__(self): def __cinit__(self):
self._c_queue = cqueue.queue_new() self._c_queue = cqueue.queue_new()
...@@ -169,7 +169,7 @@ We can thus change the init function as follows:: ...@@ -169,7 +169,7 @@ We can thus change the init function as follows::
cimport cqueue cimport cqueue
cdef class Queue: cdef class Queue:
cdef cqueue.Queue *_c_queue cdef cqueue.Queue* _c_queue
def __cinit__(self): def __cinit__(self):
self._c_queue = cqueue.queue_new() self._c_queue = cqueue.queue_new()
if self._c_queue is NULL: if self._c_queue is NULL:
...@@ -408,7 +408,7 @@ The following listing shows the complete implementation that uses ...@@ -408,7 +408,7 @@ The following listing shows the complete implementation that uses
>>> q.pop() >>> q.pop()
5 5
""" """
cdef cqueue.Queue *_c_queue cdef cqueue.Queue* _c_queue
def __cinit__(self): def __cinit__(self):
self._c_queue = cqueue.queue_new() self._c_queue = cqueue.queue_new()
if self._c_queue is NULL: if self._c_queue is NULL:
......
...@@ -27,8 +27,8 @@ and C :keyword:`struct`, :keyword:`union` or :keyword:`enum` types:: ...@@ -27,8 +27,8 @@ and C :keyword:`struct`, :keyword:`union` or :keyword:`enum` types::
float volume float volume
cdef union Food: cdef union Food:
char *spam char* spam
float *eggs float* eggs
cdef enum CheeseType: cdef enum CheeseType:
cheddar, edam, cheddar, edam,
...@@ -52,17 +52,17 @@ an anonymous :keyword:`enum` declaration for this purpose, for example:: ...@@ -52,17 +52,17 @@ an anonymous :keyword:`enum` declaration for this purpose, for example::
defining a type, not when referring to it. For example, to declare a variable defining a type, not when referring to it. For example, to declare a variable
pointing to a ``Grail`` you would write:: pointing to a ``Grail`` you would write::
cdef Grail *gp cdef Grail* gp
and not:: and not::
cdef struct Grail *gp # WRONG cdef struct Grail* gp # WRONG
There is also a ``ctypedef`` statement for giving names to types, e.g.:: There is also a ``ctypedef`` statement for giving names to types, e.g.::
ctypedef unsigned long ULong ctypedef unsigned long ULong
ctypedef int *IntPtr ctypedef int* IntPtr
Grouping multiple C declarations Grouping multiple C declarations
-------------------------------- --------------------------------
...@@ -76,9 +76,9 @@ can group them into a :keyword:`cdef` block like this:: ...@@ -76,9 +76,9 @@ can group them into a :keyword:`cdef` block like this::
int i int i
float f float f
Spam *p Spam* p
void f(Spam *s): void f(Spam* s):
print s.tons, "Tons of spam" print s.tons, "Tons of spam"
...@@ -105,7 +105,7 @@ when being called from other Cython code. ...@@ -105,7 +105,7 @@ when being called from other Cython code.
Parameters of either type of function can be declared to have C data types, Parameters of either type of function can be declared to have C data types,
using normal C declaration syntax. For example:: using normal C declaration syntax. For example::
def spam(int i, char *s): def spam(int i, char* s):
... ...
cdef int eggs(unsigned long l, float f): cdef int eggs(unsigned long l, float f):
...@@ -220,7 +220,7 @@ Some things to note: ...@@ -220,7 +220,7 @@ Some things to note:
example of a pointer-to-function declaration with an exception example of a pointer-to-function declaration with an exception
value:: value::
int (*grail)(int, char *) except -1 int (*grail)(int, char*) except -1
* You don't need to (and shouldn't) declare exception values for functions * You don't need to (and shouldn't) declare exception values for functions
which return Python objects. Remember that a function with no declared which return Python objects. Remember that a function with no declared
...@@ -234,7 +234,7 @@ It's important to understand that the except clause does not cause an error to ...@@ -234,7 +234,7 @@ It's important to understand that the except clause does not cause an error to
be raised when the specified value is returned. For example, you can't write be raised when the specified value is returned. For example, you can't write
something like:: something like::
cdef extern FILE *fopen(char *filename, char *mode) except NULL # WRONG! cdef extern FILE *fopen(char* filename, char* mode) except NULL # WRONG!
and expect an exception to be automatically raised if a call to :func:`fopen` and expect an exception to be automatically raised if a call to :func:`fopen`
returns ``NULL``. The except clause doesn't work that way; its only purpose is returns ``NULL``. The except clause doesn't work that way; its only purpose is
...@@ -243,7 +243,7 @@ function or a C function that calls Python/C API routines. To get an exception ...@@ -243,7 +243,7 @@ function or a C function that calls Python/C API routines. To get an exception
from a non-Python-aware function such as :func:`fopen`, you will have to check the from a non-Python-aware function such as :func:`fopen`, you will have to check the
return value and raise it yourself, for example:: return value and raise it yourself, for example::
cdef FILE *p cdef FILE* p
p = fopen("spam.txt", "r") p = fopen("spam.txt", "r")
if p == NULL: if p == NULL:
raise SpamError("Couldn't open the spam file") raise SpamError("Couldn't open the spam file")
...@@ -270,7 +270,7 @@ possibilities. ...@@ -270,7 +270,7 @@ possibilities.
+----------------------------+--------------------+------------------+ +----------------------------+--------------------+------------------+
| float, double, long double | int, long, float | float | | float, double, long double | int, long, float | float |
+----------------------------+--------------------+------------------+ +----------------------------+--------------------+------------------+
| char * | str/bytes | str/bytes [#]_ | | char* | str/bytes | str/bytes [#]_ |
+----------------------------+--------------------+------------------+ +----------------------------+--------------------+------------------+
| struct | | dict | | struct | | dict |
+----------------------------+--------------------+------------------+ +----------------------------+--------------------+------------------+
...@@ -281,7 +281,7 @@ Caveats when using a Python string in a C context ...@@ -281,7 +281,7 @@ Caveats when using a Python string in a C context
------------------------------------------------- -------------------------------------------------
You need to be careful when using a Python string in a context expecting a You need to be careful when using a Python string in a context expecting a
``char *``. In this situation, a pointer to the contents of the Python string is ``char*``. In this situation, a pointer to the contents of the Python string is
used, which is only valid as long as the Python string exists. So you need to used, which is only valid as long as the Python string exists. So you need to
make sure that a reference to the original Python string is held for as long make sure that a reference to the original Python string is held for as long
as the C string is needed. If you can't guarantee that the Python string will as the C string is needed. If you can't guarantee that the Python string will
...@@ -290,10 +290,10 @@ live long enough, you will need to copy the C string. ...@@ -290,10 +290,10 @@ live long enough, you will need to copy the C string.
Cython detects and prevents some mistakes of this kind. For instance, if you Cython detects and prevents some mistakes of this kind. For instance, if you
attempt something like:: attempt something like::
cdef char *s cdef char* s
s = pystring1 + pystring2 s = pystring1 + pystring2
then Cython will produce the error message ``Obtaining char * from temporary then Cython will produce the error message ``Obtaining char* from temporary
Python value``. The reason is that concatenating the two Python strings Python value``. The reason is that concatenating the two Python strings
produces a new Python string object that is referenced only by a temporary produces a new Python string object that is referenced only by a temporary
internal variable that Cython generates. As soon as the statement has finished, internal variable that Cython generates. As soon as the statement has finished,
...@@ -302,9 +302,9 @@ leaving ``s`` dangling. Since this code could not possibly work, Cython refuses ...@@ -302,9 +302,9 @@ leaving ``s`` dangling. Since this code could not possibly work, Cython refuses
compile it. compile it.
The solution is to assign the result of the concatenation to a Python The solution is to assign the result of the concatenation to a Python
variable, and then obtain the ``char *`` from that, i.e.:: variable, and then obtain the ``char*`` from that, i.e.::
cdef char *s cdef char* s
p = pystring1 + pystring2 p = pystring1 + pystring2
s = p s = p
...@@ -349,7 +349,7 @@ direct equivalent in Python. ...@@ -349,7 +349,7 @@ direct equivalent in Python.
* The null C pointer is called ``NULL``, not ``0`` (and ``NULL`` is a reserved word). * The null C pointer is called ``NULL``, not ``0`` (and ``NULL`` is a reserved word).
* Type casts are written ``<type>value`` , for example:: * Type casts are written ``<type>value`` , for example::
cdef char *p, float *q cdef char* p, float* q
p = <char*>q p = <char*>q
Scope rules Scope rules
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment