-
-
Notifications
You must be signed in to change notification settings - Fork 30.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
AC_C_CHAR_UNSIGNED from configure.ac confuses GCC 12+ by defining __CHAR_UNSIGNED__ #90671
Comments
As described at https://mail.python.org/archives/list/python-dev@python.org/thread/MPHZ3TGSHMSF7C4P7JEP2ZCYLRA3ERC5/ the AC_C_CHAR_UNSIGNED macro from configure.ac confuses GCC 12+ as it exports a reserved symbol __CHAR_UNSIGNED__ through pyconfig.h. My assumption was that AC_C_CHAR_UNSIGNED can be dropped entirely and the PR in #30851 confirmed that all the buildbots are happy with such change. Hence, I open this issue to actually do it. Thanks |
Modules/audioop.c uses __CHAR_UNSIGNED__, but the absence or presence of the symbol does not affect behavior: #if defined(__CHAR_UNSIGNED__)
#if defined(signed)
/* This module currently does not work on systems where only unsigned
characters are available. Take it out of Setup. Sorry. */
#endif
#endif |
Fedora downstream issue: https://bugzilla.redhat.com/show_bug.cgi?id=2043555 We should make sure that Python can be built with -fsigned-char *and* with -funsigned-char: build Python, but also run its test suite. |
This comment is really weird since audioop explicitly uses "signed char" and "unsigned char". Maybe to avoid any risk of confusion, the C code should use int8_t and uint8_t. |
To test if a C type is signed or not, I wrote this macro: // Test if a C type is signed.
//
// Usage: assert(_Py_CTYPE_IS_SIGNED(char)); // fail if 'char' type is unsigned
#define _Py_CTYPE_IS_SIGNED(T) (((T)-1) < 0) I planned to use it to raise an error on "import audioop" if the C "char" type is unsigned, but it seems like it's not needed, since the C extensions seems to work if char is signed or unsigned (I only read the C code, I didn't run test_audioop to actually test it). |
My audioop.c change which looks to be wrong (useless): diff --git a/Modules/audioop.c b/Modules/audioop.c
index 3aeb6f04f13..4c04b17ce7f 100644
--- a/Modules/audioop.c
+++ b/Modules/audioop.c
@@ -1948,6 +1941,13 @@ audioop_exec(PyObject* module)
{
audioop_state *state = get_audioop_state(module);
+ if (!_Py_CTYPE_IS_SIGNED(char)) {
+ PyErr_SetString(PyExc_RuntimeError,
+ "the audioop module does not support systems "
+ "where the char type is unsigned");
+ return -1;
+ }
+
state->AudioopError = PyErr_NewException("audioop.error", NULL, NULL);
if (state->AudioopError == NULL) {
return -1; |
Yeah, that looks like it's for some long-forgotten compiler that didn't implement |
The fix is in all stable branches. Thanks! |
IMO making the assumption that "char" is signed or not in C code is bad. If Python has code like that, it must be signed to explicitly use one of these types: unsigned char or uint8_t, signed char or int8_t. Hopefully, Python can now use C99 <stdint.h> since Python 3.6. On my x86-64 Fedora 35 (GCC 11.2.1), the "char" type is signed. I built Python with -funsigned-char and I ran the test suite: the whole test suite pass! Commands: --- Using ./configure CFLAGS, -funsigned-char is also used to build C extensions. Example: gcc (...) -O0 -funsigned-char (...) Modules/_elementtree.c (...) For completeness, I also built Python with -fsigned-char. Again, the full test suite passed ;-) --- |
In short, I did my checks on my side, and the merged change now LGTM. Thanks Christian for fixing it ;-) |
Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.
Show more details
GitHub fields:
bugs.python.org fields:
The text was updated successfully, but these errors were encountered: