From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 48) id 5537A3858D35; Tue, 23 Apr 2024 03:58:53 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 5537A3858D35 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1713844733; bh=AwcUO973V020TZmlcZEWOH+elM/6WzKiptZcXNXHjZM=; h=From:To:Subject:Date:From; b=l9sQSToDGGjfiCNNgfnpqGh2uhAAEqySkZcnP+tWlSWBA7JsdXWOYfIY6jK9Vj7qO RRb17oJdUnr1qQTlcNFr3FHkBMPVPqr360eJCLF6nQN5AxGZjBXvtnlHKljcNvLup2 ZI9ihQ+FYsc1XxsaENFGLaHh5zrw6JWXc20cJcV4= From: "luigighiron at gmail dot com" To: gcc-bugs@gcc.gnu.org Subject: [Bug c/114816] New: Non-standard behavior with void arguments Date: Tue, 23 Apr 2024 03:58:53 +0000 X-Bugzilla-Reason: CC X-Bugzilla-Type: new X-Bugzilla-Watch-Reason: None X-Bugzilla-Product: gcc X-Bugzilla-Component: c X-Bugzilla-Version: 14.0 X-Bugzilla-Keywords: X-Bugzilla-Severity: normal X-Bugzilla-Who: luigighiron at gmail dot com X-Bugzilla-Status: UNCONFIRMED X-Bugzilla-Resolution: X-Bugzilla-Priority: P3 X-Bugzilla-Assigned-To: unassigned at gcc dot gnu.org X-Bugzilla-Target-Milestone: --- X-Bugzilla-Flags: X-Bugzilla-Changed-Fields: bug_id short_desc product version bug_status bug_severity priority component assigned_to reporter target_milestone Message-ID: Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable X-Bugzilla-URL: http://gcc.gnu.org/bugzilla/ Auto-Submitted: auto-generated MIME-Version: 1.0 List-Id: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=3D114816 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 v= oid 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. G= CC seems to accept functions that use such arguments as long as they have name= s, 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 param= eter is const void and not void so d is a function taking an argument of type co= nst void and returning void, which means that the types of a and d are compatib= le. 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 shou= ld be valid: int main(register void){} Clang accepts this while GCC rejects. The storage class register doesn't af= fect 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 becaus= e of the following contraint: > If the expression that denotes the called function has a type that includ= es > 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 descr= ibes 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); > ^=