what value does lack of return or empty "return;" return

Discussion in 'C Programming' started by Greenhorn, Mar 3, 2005.

  1. Greenhorn

    Greenhorn Guest

    Hi,
    when a function doesn't specify a return type ,value what value is
    returned. In the below programme, the function sample()is returning the
    value passed to 'k'.

    sample(int);
    main()
    {
    int i = 0,j;
    j = sample(0);
    printf("%d", j);
    getch();
    }

    sample(k)
    {
    return;
    }
     
    Greenhorn, Mar 3, 2005
    #1
    1. Advertising

  2. Greenhorn

    Artie Gold Guest

    Greenhorn wrote:
    > Hi,
    > when a function doesn't specify a return type ,value what value is
    > returned. In the below programme, the function sample()is returning the
    > value passed to 'k'.
    >
    > sample(int);
    > main()
    > {
    > int i = 0,j;
    > j = sample(0);
    > printf("%d", j);

    No declaration? (Hint: what are you including?)
    > getch();

    No such thing.
    > }
    >
    > sample(k)
    > {
    > return;
    > }
    >

    It's undefined behavior. Could be anything. Or nasal demons might ensue.
    (The only exception is that `main()' returns 0 in C99 if no value is
    explicitly returned. You're not using C99; your program would have been
    rejected for trying to use implicit int.)

    Turn up the warning level on your compiler!

    HTH,
    --ag


    --
    Artie Gold -- Austin, Texas
    http://it-matters.blogspot.com (new post 12/5)
    http://www.cafepress.com/goldsays
     
    Artie Gold, Mar 3, 2005
    #2
    1. Advertising

  3. Greenhorn

    Kevin Bracey Guest

    In message <>
    Artie Gold <> wrote:

    > Greenhorn wrote:
    > > sample(k)
    > > {
    > > return;
    > > }
    > >

    > It's undefined behavior. Could be anything. Or nasal demons might ensue.
    > (The only exception is that `main()' returns 0 in C99 if no value is
    > explicitly returned. You're not using C99; your program would have been
    > rejected for trying to use implicit int.)


    It would also have been rejected for that return - a "return" without a value
    where one is required is now a constraint violation in C99.

    --
    Kevin Bracey, Principal Software Engineer
    Tematic Ltd Tel: +44 (0) 1223 503464
    182-190 Newmarket Road Fax: +44 (0) 1728 727430
    Cambridge, CB5 8HE, United Kingdom WWW: http://www.tematic.com/
     
    Kevin Bracey, Mar 4, 2005
    #3
  4. Greenhorn

    Artie Gold Guest

    Kevin Bracey wrote:
    > In message <>
    > Artie Gold <> wrote:
    >
    >
    >>Greenhorn wrote:
    >>
    >>>sample(k)
    >>>{
    >>> return;
    >>>}
    >>>

    >>
    >>It's undefined behavior. Could be anything. Or nasal demons might ensue.
    >>(The only exception is that `main()' returns 0 in C99 if no value is
    >>explicitly returned. You're not using C99; your program would have been
    >>rejected for trying to use implicit int.)

    >
    >
    > It would also have been rejected for that return - a "return" without a value
    > where one is required is now a constraint violation in C99.
    >

    Would it have gotten that far? Seems to me it wouldn't even parse.

    --ag

    --
    Artie Gold -- Austin, Texas
    http://it-matters.blogspot.com (new post 12/5)
    http://www.cafepress.com/goldsays
     
    Artie Gold, Mar 4, 2005
    #4
  5. Artie Gold <> writes:
    > Kevin Bracey wrote:
    >> In message <>
    >> Artie Gold <> wrote:
    >>
    >>>Greenhorn wrote:
    >>>
    >>>>sample(k)
    >>>>{
    >>>> return;
    >>>>}
    >>>>
    >>>
    >>> It's undefined behavior. Could be anything. Or nasal demons might
    >>> ensue. (The only exception is that `main()' returns 0 in C99 if no
    >>> value is explicitly returned. You're not using C99; your program
    >>> would have been rejected for trying to use implicit int.)

    >> It would also have been rejected for that return - a "return"
    >> without a value
    >> where one is required is now a constraint violation in C99.
    >>

    > Would it have gotten that far? Seems to me it wouldn't even parse.


    "return;" is perfectly legal in a function returning void. It's
    a semantic error, not a syntax error.

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
    We must do something. This is something. Therefore, we must do this.
     
    Keith Thompson, Mar 5, 2005
    #5
  6. Greenhorn

    Artie Gold Guest

    Keith Thompson wrote:
    > Artie Gold <> writes:
    >
    >>Kevin Bracey wrote:
    >>
    >>>In message <>
    >>> Artie Gold <> wrote:
    >>>
    >>>
    >>>>Greenhorn wrote:
    >>>>
    >>>>
    >>>>>sample(k)
    >>>>>{
    >>>>> return;
    >>>>>}
    >>>>>
    >>>>
    >>>>It's undefined behavior. Could be anything. Or nasal demons might
    >>>>ensue. (The only exception is that `main()' returns 0 in C99 if no
    >>>>value is explicitly returned. You're not using C99; your program
    >>>>would have been rejected for trying to use implicit int.)
    >>>
    >>>It would also have been rejected for that return - a "return"
    >>>without a value
    >>>where one is required is now a constraint violation in C99.
    >>>

    >>
    >>Would it have gotten that far? Seems to me it wouldn't even parse.

    >
    >
    > "return;" is perfectly legal in a function returning void. It's
    > a semantic error, not a syntax error.
    >

    Of course. But it's either a function returning int in C89 or nonsense
    (no return type) in C99. That's what I referring to in my `wouldn't even
    parse' comment.

    Cheers,
    --ag

    --
    Artie Gold -- Austin, Texas
    http://it-matters.blogspot.com (new post 12/5)
    http://www.cafepress.com/goldsays
     
    Artie Gold, Mar 5, 2005
    #6
  7. Artie Gold <> writes:
    > Keith Thompson wrote:
    >> Artie Gold <> writes:

    [...]
    >>>Would it have gotten that far? Seems to me it wouldn't even parse.

    >> "return;" is perfectly legal in a function returning void. It's
    >> a semantic error, not a syntax error.
    >>

    > Of course. But it's either a function returning int in C89 or nonsense
    > (no return type) in C99. That's what I referring to in my `wouldn't
    > even parse' comment.


    The term "parse" refers specifically to *syntactic* analysis.

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
    We must do something. This is something. Therefore, we must do this.
     
    Keith Thompson, Mar 5, 2005
    #7
  8. Greenhorn

    Artie Gold Guest

    Keith Thompson wrote:
    > Artie Gold <> writes:
    >
    >>Keith Thompson wrote:
    >>
    >>>Artie Gold <> writes:

    >
    > [...]
    >
    >>>>Would it have gotten that far? Seems to me it wouldn't even parse.
    >>>
    >>>"return;" is perfectly legal in a function returning void. It's
    >>>a semantic error, not a syntax error.
    >>>

    >>
    >>Of course. But it's either a function returning int in C89 or nonsense
    >>(no return type) in C99. That's what I referring to in my `wouldn't
    >>even parse' comment.

    >
    >
    > The term "parse" refers specifically to *syntactic* analysis.
    >

    Exactly.

    And and it seems to me that:

    sample(k)
    {
    return;
    }

    would choke on either the `(' or the `{'.

    Cheers,
    --ag




    --
    Artie Gold -- Austin, Texas
    http://it-matters.blogspot.com (new post 12/5)
    http://www.cafepress.com/goldsays
     
    Artie Gold, Mar 5, 2005
    #8
  9. Greenhorn

    Artie Gold Guest

    Artie Gold wrote:
    > Keith Thompson wrote:
    >
    >> Artie Gold <> writes:
    >>
    >>> Keith Thompson wrote:
    >>>
    >>>> Artie Gold <> writes:

    >>
    >>
    >> [...]
    >>
    >>>>> Would it have gotten that far? Seems to me it wouldn't even parse.
    >>>>
    >>>>
    >>>> "return;" is perfectly legal in a function returning void. It's
    >>>> a semantic error, not a syntax error.
    >>>>
    >>>
    >>> Of course. But it's either a function returning int in C89 or nonsense
    >>> (no return type) in C99. That's what I referring to in my `wouldn't
    >>> even parse' comment.

    >>
    >>
    >>
    >> The term "parse" refers specifically to *syntactic* analysis.
    >>

    > Exactly.
    >
    > And and it seems to me that:
    >
    > sample(k)
    > {
    > return;
    > }
    >
    > would choke on either the `(' or the `{'.
    >
    > Cheers,
    > --ag
    >

    Actually, I take that back -- `sample' itself would make no sense in
    that context (it's not a type).

    --ag


    --
    Artie Gold -- Austin, Texas
    http://it-matters.blogspot.com (new post 12/5)
    http://www.cafepress.com/goldsays
     
    Artie Gold, Mar 5, 2005
    #9
  10. Artie Gold <> writes:
    > Keith Thompson wrote:
    >> Artie Gold <> writes:
    >>
    >>>Keith Thompson wrote:
    >>>
    >>>>Artie Gold <> writes:

    >> [...]
    >>
    >>>>>Would it have gotten that far? Seems to me it wouldn't even parse.
    >>>>
    >>>>"return;" is perfectly legal in a function returning void. It's
    >>>>a semantic error, not a syntax error.
    >>>>
    >>>
    >>>Of course. But it's either a function returning int in C89 or nonsense
    >>>(no return type) in C99. That's what I referring to in my `wouldn't
    >>>even parse' comment.

    >> The term "parse" refers specifically to *syntactic* analysis.
    >>

    > Exactly.
    >
    > And and it seems to me that:
    >
    > sample(k)
    > {
    > return;
    > }
    >
    > would choke on either the `(' or the `{'.


    I feel like we're arguing over the most trivial aspect of this, but ...

    Parsing is based on the language grammar. The above is an old-style
    definition, but let's make it explicit:

    int sample(int k)
    {
    return;
    }

    The "return;" is invalid because it doesn't return a value. But this
    is perfectly legal:

    void sample(int k)
    {
    return;
    }

    The *parser*, when it see the "return;", doesn't remember what type
    the containing function returns. The distinction between a valid
    "return;" in a void function, and an invalid "return;" in an int
    function, cannot be made by the parser. It can only be made during
    semantic analysis.

    Conceivably the grammar could have been defined with one syntax for a
    void function definition (allowing "return;") and another for a
    non-void function definition (disallowing "return;"). Fortunately,
    this wan't necessary, since it's easy enough to detect the error
    semantically.

    In C99, this restriction is expressed as a constraint in 6.8.6.4p1:

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

    In C90, a "return;" in a non-void function is allowed (a throwback to
    K&R C, which didn't have void functions), but an attempt to use the
    function result causes undefined behavior.

    Incidentally, this is a distinction that the standard does not
    (clearly) make. Both syntactic and semantic analysis occur during
    translation phase 7. An implementation is free to mix the two in any
    way it likes.

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
    We must do something. This is something. Therefore, we must do this.
     
    Keith Thompson, Mar 5, 2005
    #10
  11. In article <>,
    Keith Thompson <> wrote:
    :The *parser*, when it see the "return;", doesn't remember what type
    :the containing function returns. The distinction between a valid
    :"return;" in a void function, and an invalid "return;" in an int
    :function, cannot be made by the parser. It can only be made during
    :semantic analysis.

    :In C99, this restriction is expressed as a constraint in 6.8.6.4p1:

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

    That's mostly detectable syntactically. One can do syntactic analysis
    to determine whether one is inside a function definition or not,
    inside a comment or not, inside an #define. Then the presence
    of the word 'void' followed by an identifier followed by
    one of the argument declaration forms, followed by a '{' intead of
    a ';', places one -syntactically- inside a void function. At that
    point, whether 'return' is followed by something other than ';'
    is a matter of syntax.

    I say "mostly detectable" because one can do all kinds of perverse
    things with the preprocessor that cannot be syntactically detected
    until after one has undergone semantic translation of the preprocessor
    directives. Even excluding #define that expand to syntactic elements,
    there is the issue of #if's that do not enclose balanced {}.

    Also, even without #if and #define, it cannot be syntactically
    detected by a simple standard regular expression, deterministic
    FSA or non-deterministic FSA (all of which are, of course, equivilent
    in expressive power), because standard RE's and FSA cannot handle
    the necessary {} matching or "" matching. A simple push-down
    automata can handle it, though, in the absence of preprocessor
    managling.
    --
    Beware of bugs in the above code; I have only proved it correct,
    not tried it. -- Donald Knuth
     
    Walter Roberson, Mar 5, 2005
    #11
  12. -cnrc.gc.ca (Walter Roberson) writes:
    > In article <>,
    > Keith Thompson <> wrote:
    > :The *parser*, when it see the "return;", doesn't remember what type
    > :the containing function returns. The distinction between a valid
    > :"return;" in a void function, and an invalid "return;" in an int
    > :function, cannot be made by the parser. It can only be made during
    > :semantic analysis.
    >
    > :In C99, this restriction is expressed as a constraint in 6.8.6.4p1:
    >
    > : A return statement with an expression shall not appear in a
    > : function whose return type is void. A return statement without an
    > : expression shall only appear in a function whose return type is
    > : void.
    >
    > That's mostly detectable syntactically. One can do syntactic analysis
    > to determine whether one is inside a function definition or not,
    > inside a comment or not, inside an #define.


    Comments are eliminated in translation phase 3; #defines vanish in
    phase 4. Parsing (syntactic analysis) doesn't occur until phase 7, so
    the parser will never see either comments or #defines.

    Certainly the parser "knows" whether it's inside a function definition
    (so a statement outside a function definition, for example, is a
    syntax error).

    > Then the presence
    > of the word 'void' followed by an identifier followed by
    > one of the argument declaration forms, followed by a '{' intead of
    > a ';', places one -syntactically- inside a void function. At that
    > point, whether 'return' is followed by something other than ';'
    > is a matter of syntax.


    If you look at the syntax definition for a function-definition:

    function-definition:
    declaration-specifiers declarator declaration-list(opt) compound-statement
    declaration-list:
    declaration
    declaration-list declaration

    you'll see that it doesn't distinguish between void and non-void
    functions.

    To illustrate how one implementation does this (though of course that
    doesn't prove anything about the standard):

    % cat tmp.c
    int foo(void)
    {
    return; /* line 3 */
    }

    return; /* line 6 */
    % gcc -c -std=c99 tmp.c
    tmp.c: In function `foo':
    tmp.c:3: warning: `return' with no value, in function returning non-void
    tmp.c: At top level:
    tmp.c:6: error: parse error before "return"

    The return statement outside the function definition causes a parse
    error; the one inside the function definition is a semantic error.

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
    We must do something. This is something. Therefore, we must do this.
     
    Keith Thompson, Mar 6, 2005
    #12
  13. Greenhorn

    CBFalconer Guest

    Keith Thompson wrote:
    >

    .... snip ...
    >
    > If you look at the syntax definition for a function-definition:
    >
    > function-definition:
    > declaration-specifiers declarator declaration-list(opt) compound-statement
    > declaration-list:
    > declaration
    > declaration-list declaration
    >
    > you'll see that it doesn't distinguish between void and non-void
    > functions.


    Which is probably due to the BNF specified in the standard (haven't
    checked). However there is no reason the parsing code cannot
    differentiate and yield errors, nor that the BNF cannot be written
    to separate functions and 'procedures'. In practice the freedom to
    reorder components in the source (static const int vs const static
    int etc.) makes this awkward. C has too many ways to arrive at the
    same place.


    --
    "If you want to post a followup via groups.google.com, don't use
    the broken "Reply" link at the bottom of the article. Click on
    "show options" at the top of the article, then click on the
    "Reply" at the bottom of the article headers." - Keith Thompson
     
    CBFalconer, Mar 6, 2005
    #13
  14. Greenhorn

    Chris Torek Guest

    >Keith Thompson wrote:
    >>If you look at the [C89 or C99] syntax definition for a
    >>function-definition ... you'll see that it doesn't distinguish
    >>between void and non-void functions.


    [He goes on to note that this is one reason C compilers treat
    "return without a value in a non-void function" as a semantic error
    rather than a syntactic one.]

    In article <>
    CBFalconer <> wrote:
    >Which is probably due to the BNF specified in the standard (haven't
    >checked).


    That is what Keith Thompson just said. :) The syntax in the
    C standards is specified that way.

    >However there is no reason the parsing code cannot
    >differentiate and yield errors, nor that the BNF cannot be written
    >to separate functions and 'procedures'. In practice the freedom to
    >reorder components in the source (static const int vs const static
    >int etc.) makes this awkward. C has too many ways to arrive at the
    >same place.


    Indeed, this is true for C99. For C89, however, "return without a
    value" *is* allowed, even in a non-void function:

    double f(int *ip) {
    if (ip != NULL) {
    *ip = 1;
    return;
    }
    return 3.1415926535897932384626433832795;
    }

    is a legal (albeit rather pointless) C89 function, which can be
    called from code such as:

    void g(void) {
    int x;
    double y;

    f(&x);
    y = f(NULL);
    }

    If you wish to accept syntactically-valid C89 code, then, you cannot
    make "return without a value in non-void function" into the kind
    of error that changes code-generation (syntax errors usually suppress
    it entirely, or at the least, remove a few needed nodes from the
    parse tree, so that wrong code will come out of the back end of
    the compiler).

    (Note that C compilers are always allowed to produce diagnostics,
    even spurious ones, so:

    foo.c, line 3: warning: in function f(): return without a value,
    in function with return type "double"

    is allowed, even in C89, even though the code is technically OK,
    however ugly it may be.)
    --
    In-Real-Life: Chris Torek, Wind River Systems
    Salt Lake City, UT, USA (40°39.22'N, 111°50.29'W) +1 801 277 2603
    email: forget about it http://web.torek.net/torek/index.html
    Reading email is like searching for food in the garbage, thanks to spammers.
     
    Chris Torek, Mar 6, 2005
    #14
  15. In article <>,
    Keith Thompson <> wrote:
    |-cnrc.gc.ca (Walter Roberson) writes:
    |> In article <>,
    |> Keith Thompson <> wrote:
    |> :The *parser*, when it see the "return;", doesn't remember what type
    |> :the containing function returns. The distinction between a valid
    |> :"return;" in a void function, and an invalid "return;" in an int
    |> :function, cannot be made by the parser. It can only be made during
    |> :semantic analysis.

    |> Then the presence
    |> of the word 'void' followed by an identifier followed by
    |> one of the argument declaration forms, followed by a '{' intead of
    |> a ';', places one -syntactically- inside a void function. At that
    |> point, whether 'return' is followed by something other than ';'
    |> is a matter of syntax.


    |If you look at the syntax definition for a function-definition:

    |you'll see that it doesn't distinguish between void and non-void
    |functions.

    If you look at what you wrote, you said that certain kinds of
    validity checks on 'return' statements "cannot be made by the
    parser" and "can only be made during semantics analysis".

    I showed that this is incorrect: that once past preprocessing,
    a parser *could* syntatically determine whether a void function
    had a non-void return.

    I did not say that a parser -must- so determine, and I didn't
    say that there was a distinction at the BNF level: I just pointed
    out that the recognition *could* be made by the parser.

    If you had written that the distinction "is not" made by the parser
    then you would be talking about implimentation, and might be correct
    for all existing parsers -- but you wrote "cannot", which means
    "not possible", and I showed that at least part of it is possible.
    --
    Studies show that the average reader ignores 106% of all statistics
    they see in .signatures.
     
    Walter Roberson, Mar 6, 2005
    #15
  16. -cnrc.gc.ca (Walter Roberson) writes:
    [...]
    > If you had written that the distinction "is not" made by the parser
    > then you would be talking about implimentation, and might be correct
    > for all existing parsers -- but you wrote "cannot", which means
    > "not possible", and I showed that at least part of it is possible.


    Ok, it's possible.

    My original point was to refute someone else's statement that a
    "return;" in a non-void function "wouldn't even parse". In fact it
    could, and almost certainly would. I got a little carried away in
    implying that it *must* parse.

    You're right, a C99 compiler (but not a C90 compiler) *could* use
    separate grammar productions for void and non-void function
    definitions, and thereby catch "return;" as a syntax error. (There's
    no requirement for a compiler to use the grammar in the standard, as
    long as it uses one that lets it catch errors and process correct
    code.) It would require some extra work for the case of a function
    whose return type is a typedef for void, but that shouldn't be any
    more difficult than typedef handling in general.

    It would be a perverse implementation. Semantic errors are easier to
    handle within the compiler than syntax errors. For a semantic error,
    the compiler can just issue a diagnostic, set a flag indicating that
    the compilation will fail, and move on; for a syntax error, it has to
    either reconstruct a guessed valid parse so it can continue
    processing, or give up and die.

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
    We must do something. This is something. Therefore, we must do this.
     
    Keith Thompson, Mar 6, 2005
    #16
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Christopher Blunck
    Replies:
    0
    Views:
    1,202
    Christopher Blunck
    Jun 24, 2003
  2. Mark 'Kamikaze' Hughes

    Re: does lack of type declarations make Python unsafe?

    Mark 'Kamikaze' Hughes, Jun 29, 2003, in forum: Python
    Replies:
    4
    Views:
    819
    Anton Vredegoor
    Jul 1, 2003
  3. Anton Vredegoor
    Replies:
    4
    Views:
    839
  4. David Abrahams
    Replies:
    0
    Views:
    680
    David Abrahams
    Jun 30, 2003
  5. Cameron Laird
    Replies:
    9
    Views:
    374
    Peter Hansen
    Jul 8, 2003
Loading...

Share This Page