New submission from Alexey Izbyshev <izbys...@ispras.ru>:

This issue is a follow-up of msg329608 of #35081.

GCC and Clang have -Wmissing-prototypes[1] diagnostic that is reported if a 
global function is defined without a previous declaration containing a 
prototype. The reasons may be the following:

1) The header where it is declared is not included before the definition.
2) There is a declaration before the definition, but it doesn't contain a 
prototype (e.g., "int foo()").
3) There is no separate declaration of the function in the project at all.

(1) is undesirable because the compiler can't check that signatures of the 
declaration and the definition match. If they don't, subtle issues may occur 
when such function is called using a wrong declaration.

(2) is undesirable too because there is usually no reason to use declarations 
without prototypes. Often "int foo()" was meant to be "int foo(void)" -- these 
two have different meaning in C.

(3) may mean that either the function is unused (which is probably undesirable) 
or it was intentionally defined without a declaration. One case when the latter 
makes sense is plugin-like files which define initialization functions or 
similar external entry points. Those may be called via pointers obtained with 
dlsym() or have calls generated at compile time, like Modules/config.c in 
CPython.

It would be good to enable -Wmissing-prototypes to catch (1) and (2) -- such 
issues exist as of time of this report. However, (3) is a problem because of 
module initialization functions which would cause unwanted diagnostics.

There is no function attribute that could be put in PyMODINIT_FUNC macro to 
suppress the diagnostic for a single function. The general diagnostic 
suppression machinery (#pragma GCC diagnostic[2]) affects everything on the 
following lines, and while the state can be saved and restored via "#pragma GCC 
diagnostic push/pop", we'd either need another macro to restore the state after 
the end of module initializer definitions or require that initializers always 
come last in the file.

A workaround is to declare the initializer inside PyMODINIT_FUNC (or a new 
macro). For example (omitting platform-specific parts of PyMODINIT_FUNC):

#define PyMODINIT_FUNC(name) \
    extern PyObject *name(void); \
    PyObject *name(void)

PyMODINIT_FUNC(PyInit_time)
{
  ...
}

I've also noticed that PyMODINIT_FUNC is used for functions with a different 
signature in Modules/_testmultiphase.c, so either another macro would be needed 
for that, or a general macro accepting a prototype as its variadic parameter 
could be added.

Even if it's deemed infeasible to enable -Wmissing-prototypes by default,
developers may find it useful to ensure that the diagnostic is reported only 
for files in Modules directory.

[1] https://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html
[2] https://gcc.gnu.org/onlinedocs/gcc/Diagnostic-Pragmas.html

----------
components: Build
messages: 329954
nosy: izbyshev, vstinner
priority: normal
severity: normal
status: open
title: Consider enabling -Wmissing-prototypes
type: enhancement
versions: Python 3.8

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

Reply via email to