https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114816
Bug ID: 114816 Summary: Non-standard behavior with void arguments Product: gcc Version: 14.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c Assignee: unassigned at gcc dot gnu.org Reporter: luigighiron at gmail dot com Target Milestone: --- After thinking about qualified void return types I decided to think about void function parameters: > The special case of an unnamed parameter of type void as the only item in > the list specifies that the function has no parameters. Section 6.7.6.3 "Function declarators (including prototypes)" Paragraph 10 ISO/IEC 9899:2018 No other restrictions are present that would forbid void parameter types. GCC seems to accept functions that use such arguments as long as they have names, for example: void a(void x); void b(const void x,register void y,register volatile void z); Are accepted by GCC, but the following declarations are not accepted by GCC when they should be valid: void c(void,void); void d(const void); Other incomplete types are accepted by GCC. Note that the type of the parameter is const void and not void so d is a function taking an argument of type const void and returning void, which means that the types of a and d are compatible. The storage class register can be used on arguments and the same is true for void arguments, which doesn't affect the type so the following program should be valid: int main(register void){} Clang accepts this while GCC rejects. The storage class register doesn't affect the type and it is still one unnamed parameter of type void so this should be a declaration for zero arguments. Calling any function with a void parameter is a constraint violation because of the following contraint: > If the expression that denotes the called function has a type that includes > a prototype, the number of arguments shall agree with the number of > parameters. Each argument shall have a type such that its value may be > assigned to an object with the unqualified version of the type of its > corresponding parameter. Section 6.5.2.2 "Function calls" Paragraph 2 ISO/IEC 9899:2018 GCC does not diagnose the error and instead just interprets the first void argument as being a sentinel value indicating when the arguments end, for example with the function a from before GCC accepts calling it with zero arguments. Qualified versions of void for example with the function b from before are properly diagnosed. When referencing a function type with a single void parameter GCC will omit the name of the parameter as usual which leads to some confusing error messages, for example: void f(void x); void f(void); The error message indicates that these types are incompatible, but it describes the first declaration as having type void(void). Here is the error output omitting source locations: > error: conflicting types for 'f'; have 'void(void)' > void f(void); > ^ > note: previous declaration of 'f' with type 'void(void)' > void f(void x); > ^