Macros defined in CPython headers -> move to function-like macros

Hi All,
I hope I am not breaking any rules by posting here. I maintain a number of libraries and C++ Python extensions and one slightly annoying thing about the Python.h headers is that it includes headers defining macros such as *snprintf*.
In C++, this collides with std::snprintf defined in the <cstdio>. One backward-compatible way to make these collision less likely would be to make this macro a function-style macro - so that we could prevent the macro expansion in client code by simply adding parentheses to the calls to the actual functions.
(std::snprintf)(foobar)
In my opinion, it would make the world a better place for C++ Python extension authors :)
Best,
Sylvain

Hi,
Do you have issues with other macros than snprintf?
In pyerrors.h, I see:
#if defined(MS_WIN32) && !defined(HAVE_SNPRINTF) # define HAVE_SNPRINTF # define snprintf _snprintf # define vsnprintf _vsnprintf #endif
A minimum fix would be to not define these functions if __cplusplus__ macro is defined.
I suggest you to open an issue at https://bugs.python.org/
Victor
Le jeu. 9 avr. 2020 à 12:24, Sylvain Corlay <sylvain.corlay@gmail.com> a écrit :
-- Night gathers, and now my watch begins. It shall not end until my death.

At the moment, only snprintf pauses issues, but I presume that there are others similar cases.
Doing the following instead:
#define snprintf(...) _snprintf(__VA_ARGS__) #define vsnprintf(...) _vsnprintf(__VA_ARGS__)
would allow the client code to protect from macro expansion with parentheses when they need to. I think that it would be backward compatible.
Best,
On Thu, Apr 9, 2020 at 5:30 PM Victor Stinner <vstinner@python.org> wrote:

Is "#define snprintf(...)" syntax supported by C99? Since Python 3.6, Python requires a sub-set of C99: https://www.python.org/dev/peps/pep-0007/#c-dialect
By the way, Python code base still uses:
#ifdef HAVE_STDARG_PROTOTYPES va_start(vargs, format); #else va_start(vargs); #endif
I'm not sure if we still need to support platforms which don't accept a second parameter to va_start().
Victor
Le jeu. 9 avr. 2020 à 17:38, Sylvain Corlay <sylvain.corlay@gmail.com> a écrit :
-- Night gathers, and now my watch begins. It shall not end until my death.

On 2020-04-09 12:23, Sylvain Corlay wrote:
This is already reported: https://bugs.python.org/issue36020
Python should use PyOS_snprintf instead where possible.
(Unfortunately I don't currently have time to work on this.)

Is "#define snprintf(...)" syntax supported by C99? Since Python 3.6
This is a C preprocessor feature, not C++, so I would be surprised that it is not supported.
I agree. My proposed fix was just in case people relied on this macro (by calling it), to be backward compatible.
This fix would still break people who used the macro to refer to a function pointer though - but I find this incredibly unlikely.
S.
On Thu, Apr 9, 2020 at 8:06 PM Petr Viktorin <encukou@gmail.com> wrote:

Hi,
Do you have issues with other macros than snprintf?
In pyerrors.h, I see:
#if defined(MS_WIN32) && !defined(HAVE_SNPRINTF) # define HAVE_SNPRINTF # define snprintf _snprintf # define vsnprintf _vsnprintf #endif
A minimum fix would be to not define these functions if __cplusplus__ macro is defined.
I suggest you to open an issue at https://bugs.python.org/
Victor
Le jeu. 9 avr. 2020 à 12:24, Sylvain Corlay <sylvain.corlay@gmail.com> a écrit :
-- Night gathers, and now my watch begins. It shall not end until my death.

At the moment, only snprintf pauses issues, but I presume that there are others similar cases.
Doing the following instead:
#define snprintf(...) _snprintf(__VA_ARGS__) #define vsnprintf(...) _vsnprintf(__VA_ARGS__)
would allow the client code to protect from macro expansion with parentheses when they need to. I think that it would be backward compatible.
Best,
On Thu, Apr 9, 2020 at 5:30 PM Victor Stinner <vstinner@python.org> wrote:

Is "#define snprintf(...)" syntax supported by C99? Since Python 3.6, Python requires a sub-set of C99: https://www.python.org/dev/peps/pep-0007/#c-dialect
By the way, Python code base still uses:
#ifdef HAVE_STDARG_PROTOTYPES va_start(vargs, format); #else va_start(vargs); #endif
I'm not sure if we still need to support platforms which don't accept a second parameter to va_start().
Victor
Le jeu. 9 avr. 2020 à 17:38, Sylvain Corlay <sylvain.corlay@gmail.com> a écrit :
-- Night gathers, and now my watch begins. It shall not end until my death.

On 2020-04-09 12:23, Sylvain Corlay wrote:
This is already reported: https://bugs.python.org/issue36020
Python should use PyOS_snprintf instead where possible.
(Unfortunately I don't currently have time to work on this.)

Is "#define snprintf(...)" syntax supported by C99? Since Python 3.6
This is a C preprocessor feature, not C++, so I would be surprised that it is not supported.
I agree. My proposed fix was just in case people relied on this macro (by calling it), to be backward compatible.
This fix would still break people who used the macro to refer to a function pointer though - but I find this incredibly unlikely.
S.
On Thu, Apr 9, 2020 at 8:06 PM Petr Viktorin <encukou@gmail.com> wrote:
participants (4)
-
Antoine Pitrou
-
Petr Viktorin
-
Sylvain Corlay
-
Victor Stinner