#2158 Expression in return statement in function that returns void

closed-fixed
None
Front-end
5
2013-12-22
2013-04-29
No

Regression test gcc-torture-execute-20000314-3.c passes in trunk.
I had a closer look at it today, when I noticed it fails in the stm8 branch.

To me it looks as if this regression test has a return statement with expression in a function that returns void. This is forbidden by the C99 and C11 standards (don't know about earlier), first paragraph in section 6.8.6.4.

I suggest to make the front-end report an error for such return statements, and remove the regression test gcc-torture-execute-20000314-3.c.

Philipp

Discussion

  • Erik Petrich

    Erik Petrich - 2013-05-26

    It's also forbidden in C89/90. The only time this might be allowed is in very old dialects that had the void keyword but before the semantics for void were standardized (some sort of enhanced K&R). Since we are trying to follow standards, I agree with your suggestion.

     
  • Maarten Brock

    Maarten Brock - 2013-12-19

    But the expression is of type void! Is it then also forbidden? I certainly would like it to be allowed.

    void foo(void);
    void bar(void)
    {
        return foo();
    }
    

    And I doubt this test was about testing returning void functions. Instead of removing it could easily have been fixed.

    All-in-all I disgree with the removal.
    Your opinions are welcome.

     
  • Maarten Brock

    Maarten Brock - 2013-12-19

    Oh and SDCC does generate an error 58 (void function returning value) when an non-void expression is returned in a void-function.

     
  • Philipp Klaus Krause

    The wording in the standard is quite clear:

    "A return statement with an expression shall not appear in a function whose return type is void."

    We really should emit an error (or at least a warning, but I don't see a use case for having an expression of type void in a return statement).

    Philipp

     
  • Philipp Klaus Krause

    To me, the regression test looks like it was meant to test the passing of parameters for function calls that occur in expressions in return statements in void functions.

    Philipp

     
  • Maarten Brock

    Maarten Brock - 2013-12-19

    The use case is obvious. You don't have to change the code when the return type changes and you don't need curly braces. E.g.:

    typedef ret_type void; /* or int */
    ret_type foo(char);
    ret_type bar(char a)
    {
        if (a)
            return foo(a);
    }
    

    I find this very elegant code. Now compare this to what it requires when it's not allowed:

    #define USE_VOID
    #ifdef USE_VOID
    typedef ret_type void;
    #else
    typedef ret_type int;
    #endif
    ret_type foo(char);
    ret_type bar(char a)
    {
        if (a)
        {
    #ifdef USE_VOID
            foo(a);
            return;
    #else
            return foo(a);
    #endif
        }
    }
    

    And this construct can recurse quite a few levels up!

    I have no problem with limiting this to --std-sdccXX only as it appears to be non-standard. I suggest no warning for --std-sdccXX and error 58 for --std-cXX.

    Maarten

     
  • Maarten Brock

    Maarten Brock - 2013-12-22

    Reintroduced regression test gcc-torture-execute-20000314-3.c.
    Fixed stm8 genReturn to allow returning 0 bytes.
    But generate error 58 in SDCCast.c when not using sdcc extensions (--std-sdccXX or pragma).

     
  • Maarten Brock

    Maarten Brock - 2013-12-22
    • status: open --> closed-fixed
    • assigned_to: Maarten Brock
     

Log in to post a comment.