Dennis Sweeney <sweeney.dennis...@gmail.com> added the comment:

I think this question is about types in c, apart from any Python c API. 

According to https://docs.python.org/3/c-api/arg.html#numbers, the specifier is

    c: (bytes or bytearray of length 1) -> [char]

so you should be able to write to a c variable of type "char". In c, "signed 
char"s are signed, with values in [-128..127]. C also has an "unsigned char" 
type, with values in [0..255]. Both types of variables contain eight bits of 
information, but they are interpreted in different ways. As such, we can write 
something like this:

    signed char c1;
    unsigned char c2;
    PyObject *tup = Py_BuildValue("(c)", 0xff);

    PyArg_ParseTuple(tup, "c", &c1);
    PyArg_ParseTuple(tup, "c", &c2);

    if (c1 < 0) {
        printf("First is signed.\n");
    }
    else {
        printf("First is unsigned.\n");
    }

    if (c2 < 0) {
        printf("Second is signed.\n");
    }
    else {
        printf("Second is unsigned.\n");
    }

and get back:

    First is signed.
    Second is unsigned.

Here, c1 and c2 each store nothing but the eight bits 0b11111111 (a.k.a. 0xff), 
but the compiler interprets c1 in two's-complement as -1 whereas it interprets 
c2 as 255, simply based on variable types.

If you just care about which eight bits you have, using "char" is good enough, 
and comparing "char"s for equality is all well and good. But if you're doing 
arithmetic or numerical comparisons on chars, I believe it's best practice to 
explicitly declare "signed" or "unsigned", since it's implementation-defined 
which one the compiler will do if you don't specify.

Note that if you replace 0xff with -1 in the c code above, the result will 
probably be the same, since the int -1 will be cast to the the same least 
significant byte as 0xff (the upper bytes are thrown away).

(A technicality: even the bounds for the number of bits in a char are 
implementation-specific, but unsigned chars must support *at least* [-127..127] 
and signed chars must support *at least* [0..255], and implementation using 
more than 8 bits are quite rare. If you wanted to be totally sure about exactly 
the types you're using, you could technically use uint8_t or int8_t.)

----------
nosy: +Dennis Sweeney

_______________________________________
Python tracker <rep...@bugs.python.org>
<https://bugs.python.org/issue40085>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com

Reply via email to