public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug c/114816] New: Non-standard behavior with void arguments
@ 2024-04-23  3:58 luigighiron at gmail dot com
  2024-04-23 12:06 ` [Bug c/114816] " jsm28 at gcc dot gnu.org
  0 siblings, 1 reply; 2+ messages in thread
From: luigighiron at gmail dot com @ 2024-04-23  3:58 UTC (permalink / raw)
  To: gcc-bugs

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);
>      ^

^ permalink raw reply	[flat|nested] 2+ messages in thread

* [Bug c/114816] Non-standard behavior with void arguments
  2024-04-23  3:58 [Bug c/114816] New: Non-standard behavior with void arguments luigighiron at gmail dot com
@ 2024-04-23 12:06 ` jsm28 at gcc dot gnu.org
  0 siblings, 0 replies; 2+ messages in thread
From: jsm28 at gcc dot gnu.org @ 2024-04-23 12:06 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114816

--- Comment #1 from Joseph S. Myers <jsm28 at gcc dot gnu.org> ---
Note that it's not possible to define a function with such parameters ("After
adjustment, the parameters in a parameter type list in a function declarator
that is part of a definition of that function shall not have incomplete
type.").

"register void" and "const void" (single unnamed parameter) are in the list of
undefined behavior in Annex J ("A storage-class specifier or type qualifier
modifies the keyword void as a function parameter type list") - presumably
implicitly undefined for lack of definition. As for named void parameters (or
more than one void parameter, etc.), the response to C99 DR#295 says "The
Committee agrees that there do not appear to be any constraints forbidding
constructions like void func(void parm); nor are any semantics provided for
this construction." (which would also be implicitly undefined behavior).

Given the desire to reduce undefined behavior in C2y it would be reasonable to
submit a paper tightening this up by making all the problem cases (any case of
a void parameter except for the special case of a single unnamed parameter of
type void, no storage class specifier, no ellipsis following) into constraint
violations for function declarators - or indeed to raise this through the issue
tracking process once we have the new issue tracker set up, with a view to
inviting WG14 to consider this a defect applicable to older standard versions.

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2024-04-23 12:06 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2024-04-23  3:58 [Bug c/114816] New: Non-standard behavior with void arguments luigighiron at gmail dot com
2024-04-23 12:06 ` [Bug c/114816] " jsm28 at gcc dot gnu.org

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).