I am cross compiling Python 3.5.2 for use on a 32-bit ARM processor with Linux. I use socket.CAN_EFF_FLAG and noticed that it is negative on the target despite being positive on my host (64-bit Intel Linux). Host: altendky@tp:~$ uname -a Linux tp 4.4.0-31-generic #50-Ubuntu SMP Wed Jul 13 00:07:12 UTC 2016 x86_64 x86_64 x86_64 GNU/Linux altendky@tp:~$ python3 --version Python 3.5.2 altendky@tp:~$ python3 -c 'import socket; print(socket.CAN_EFF_FLAG)' 2147483648 ^^ Is expected Target: root@rosi ~$ uname -a Linux rosi 3.0.101-rt130-opusa3-2.1.0-2 #1 PREEMPT Tue Apr 12 13:49:26 CEST 2016 armv6l GNU/Linux root@rosi ~$ /opt/epc/bin/python3 --version Python 3.5.2 root@rosi ~$ /opt/epc/bin/python3 -c 'import socket; print(socket.CAN_EFF_FLAG)' -2147483648 ^^ Is not expected to be negative Only CAN_EFF_FLAG reference in my source used to cross build Python: Modules/socketmodule.c: PyModule_AddIntMacro(m, CAN_EFF_FLAG); Definition in cross compiler include: altendky@tp:/opt/freescale/usr/local/gcc-4.6.2-glibc-2.13-linaro-multilib-2011.12/fsl-linaro-toolchain/arm-fsl-linux-gnueabi/multi-libs/default/usr/include$ grep -r CAN_EFF_FLAG linux/can.h:#define CAN_EFF_FLAG 0x80000000U /* EFF/SFF is set in the MSB */ For reference, here it is on the host system (looks the same to me): altendky@tp:/usr/include$ grep -r CAN_EFF_FLAG linux/can.h:#define CAN_EFF_FLAG 0x80000000U /* EFF/SFF is set in the MSB */ But perhaps this `long` type for the value is the issue? If signed and only 4-bytes as is the case on my target then this will misinterpret the 0x80000000U literal resulting in the above observed -2147483648. PyModule_AddIntConstant(PyObject *m, const char *name, long value) On my target system, printf("%d", sizeof(long)) yields 4. For now I just work around it in my application by reassigning it to be it's absolute value. socket.CAN_EFF_FLAG = abs(socket.CAN_EFF_FLAG)
The constant is an unsigned long but PyModule_AddIntConstant() takes a signed long. You have to write your own function that uses PyLong_FromUnsignedLong() and PyModule_AddObject(). Do you get a compiler warning because 0x80000000U is larger than (1<<31)-1?
Oh sorry, I missed the point that you are talking about an existing constant in the socket module. At first I thought that you were referring to a constant that you have added. It sounds like a bug for constants >= 2**31.
I do not seem to be getting a compiler warning. arm-fsl-linux-gnueabi-gcc -Wno-unused-result -Wsign-compare -DNDEBUG -g -fwrapv -O3 -Wall -Wstrict-prototypes -Werror=declaration-after-statement -I. -IInclude -I./Include -I"/epc/t/262/misc-build-arm-fsl-linux-gnueabi/sysroot/root/all//opt/epc/include" -DPy_BUILD_CORE -c ./Modules/socketmodule.c -o Modules/socketmodule.o To really encompass all cases I think you are correct that both a signed and an unsigned handler are needed. Though, I have an idea for something nifty, I'll share if it works. Regardless, shouldn't they use `intmax_t` and `uintmax_t` from stdtypes.h to make sure they handle anything that could be defined in the referenced C code? In my case simply switching from `long` to `intmax_t` would be sufficient. Note that I am not worried about getting this fixed for my one case. My workaround is fine for my application. I also will hopefully be correcting the subject to >=2**31 if this change does what I think. Good ol' off-by-one.
messages: + title: PyModule_AddIntConstant() wraps >=2^32 values when long is 4 bytes -> PyModule_AddIntConstant() wraps >=2^31 values when long is 4 bytes