Re: [C] return statement in void function?

From: Arthur J. O'Dwyer (ajo_at_nospam.andrew.cmu.edu)
Date: 01/12/04


Date: Mon, 12 Jan 2004 11:26:57 -0500 (EST)


On Mon, 12 Jan 2004, Lyn Powell wrote:
>
> "Anthony Borla" <ajborla@bigpond.com> wrote
> > > "Arthur J. O'Dwyer" <ajo@nospam.andrew.cmu.edu> wrote
> > > On Mon, 12 Jan 2004, Anthony Borla wrote:
> > > >
> > > > You may be interested to know that you can do this
> > > [in C++, that is]:
> > > >
> > > > void f() { return void(); }
> > > >
> > > > as is this:
> > > >
> > > > void g() {}
> > > > void h() { return g(); }
> > > >
> > > > Yes, it may seem strange, but it is allowed [I suspect] to
> > > > maintain syntactic consistency.
> > >
> > > However, both of these tricks are not allowed in C.
> > >
> > > C++, as far as I know, allows them; but the first is
> > > a syntax error in C and the second one, despite maybe
> > > being "consistent," doesn't have any advantage
> > > over
> > >
> > > void h() { g(); return; }
> > >
> > > which is probably why C doesn't bother to allow it.
> >
> > This:
> >
> > void f() { return void(); }
> >
> > is not legal C because the language doesn't support temporary objects [let
> > alone permanent ones ;)].
>
> C supports temporary objects, you just have to be a little more lenient in
> what you consider to be an object. For example, in a complex expression a C
> compiler will probably introduce temporary values to help in the
> calculation.

  Not in any sense consistent with the standard, though. In the
expression (1+2)+4, yes, the integer 3 is going to be stored somewhere
"temporarily," but according to the language definition, that 3 is *not*
stored as an "object" -- it's just a quirk of the implementation.
[I'm ignoring the constant-ness of (1+2)+4 for simplicity's sake.]
  But in cases like

  struct foo copy(struct foo x) {
     struct foo y = x;
     return y;
  }

a "temporary object" might IMHO be reasonably said to be created
somewhere for the purpose of returning that struct by value. And C99
allows the programmer to write

  (void) foo( ((struct foo){0, "fred", 3.14}) );

in which case we have a truly anonymous "temporary" object that the
compiler really does have to think about. :)

> > I suspect the following:
> >
> > void g() {}
> > void h() { return g(); }
> >
> > is also allowed in C++ as a consequence of temporary object support since:

  Someone (Uli?) gave a very reasonable explanation elsethread: it allows
the C++ programmer to use constructs like

  template <typename T, typename U>
  T foo ( U fxn )
  { return fxn(); }

without worrying as much about the special case where U = 'void(*)()'.
Except he probably gave a less stupid example. ;-)

> >
> > return g();
> >
> > is probably optimised to:
> >
> > return void();

  Even in C++, these statements have different effect -- the former
evaluates g(), and the latter does not!

> > Thus, this is illegal in C for the same reason ?
>
> It's not illegal in C, but some compilers will feel obliged to give you
> a warning about a void function returning a value even though the value
> evaluates to void.

  In N869, I see:

       6.8.6.4 The return statement

       Constraints

       [#1] 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.

So you would seem to be wrong. (See also 6.3.2.2#1: "The (nonexistent)
value of a void expression [...] shall not be used in any way [...]"

-Arthur



Relevant Pages

  • Re: fields for methods?
    ... but only by a compiler that is allowed to ... struct A {void foo();}; ... int static_instance i = 0; ... Is not possible because foo is the only member of A... ...
    (comp.programming)
  • Re: linking C++ functions in a C program
    ... contains one function named foo() which is compiled in C, ... Therefore, no matter how you classify bar(), this program ... void foo; ... guess the compiler can generate two references to foo, one adorned, ...
    (comp.lang.c)
  • Re: linking C++ functions in a C program
    ... contains one function named foo() which is compiled in C, ... Therefore, no matter how you classify bar(), this program ... void foo; ... The C++ compiler processing main.C will see an extern "C" function named foo, and any time that C++ code calls it, it will call the unmangled C name instead of the default mangled C++ name. ...
    (comp.lang.c)
  • Re: Pointers to Functions
    ... >>inline void foo{ ... >>int main{ ... Yes it is using the latest VC++ optimising compiler, ... This is fine as the identifier foo is a const pointer to the function ...
    (alt.comp.lang.learn.c-cpp)
  • Re: fields for methods?
    ... void A::foo{ ... but only by a compiler that is allowed to ... int static_instance i = 0; ... it totally breaks the idea of encapsulation, which is the reason a lot ...
    (comp.programming)

Loading