Omitting return in non-void function

A

amit.codename13

does omitting return in an non-void function invoke undefined behavior
if the value of the function call is not used in the calling
function???
 
R

Ralf Damaschke

does omitting return in an non-void function invoke undefined behavior
if the value of the function call is not used in the calling
function???

As far as I can tell, no. There is 6.9.1p12:

If the } that terminates a function is reached, and the value of the
function call is used by the caller, the behavior is undefined.

There is no other requirement for not returning a value for a non-void
functions (at least none that I found and apart from 6.8.6.4 which from
C99 on forbids "return;" for a function returning a non-void value).

-- Ralf
 
F

Flash Gordon

does omitting return in an non-void function invoke undefined behavior
if the value of the function call is not used in the calling
function???

No, but it is incredibly bad style.
 
C

CBFalconer

Ralf said:
As far as I can tell, no. There is 6.9.1p12:

If the } that terminates a function is reached, and the
value of the function call is used by the caller, the
behavior is undefined.
^^^^^^^^^^^^^^^^^^^^^

In other words, YES, as specified by the standard portion you
quoted.
 
A

amit.codename13

CBFalconer said:





In other other words, NO, as specified by the Standard portion he
quoted.

--
Richard Heathfield <http://www.cpax.org.uk>
Email: -http://www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999

Can you pls comment on the following reasoning...
Undefined behavior is otherwise indicated in this International
Standard by the words ‘‘undefined behavior’’ or by the omission of any explicit definition
of behavior. There is no difference in emphasis among these three; they all describe
‘‘behavior that is undefined’’.

There is no(pls correct if there is one) mention of the behavior when
a return statement is missing in a non-void function and the value of
the function call is not used by the caller

so shouldn't this be an undefined behvaior???
 
K

Keith Thompson

Richard Heathfield said:
(e-mail address removed) said:



No, it shouldn't. Chuck Falconer is mistaken; the Standard does
define the behaviour of code where a function's return value is not
only not provided but also not used, and the evidence you need is
here:

C89 3.6.6.4: "If a return statement without an expression is
executed, and the value of the function call is used by the caller,
the behavior is undefined. Reaching the } that terminates a
function is equivalent to executing a return statement without an
expression."

We have similar wording in C99 6.9.1(12): "If the } that terminates
a function is reached, and the value of the function call is used
by the caller, the behavior is undefined."

This is an example of a simple (yet much-misunderstood) maxim: "the
exception proves the rule". If you park in a street bay next to a
sign saying "NO PARKING Mon-Sat 8am-6pm" and it's actually after
6pm or before 8am or a Sunday, can you park there? Yes, of course.
The sign draws your attention to the exception. The rule is the
complement of any exceptions.

In this case, the exception is very carefully delineated by the
Standard: IF a return statement without an expression is executed
AND the value of the function call is used by the caller, THEN the
behaviour is undefined. Therefore, *unless the Standard says
otherwise* (which it doesn't), the given exception proves the rule
that if a return statement without an expression is executed and
the value of the function call is NOT used by the caller, that
behaviour is well-defined.

On the other hand, just because the behavior is explicitly undefined
in a certain case, that doesn't define the behavior in other cases.
The fact that the standard says the behavior is undefined in this
particular case strongly suggests that the behavior is defined in
other cases, but it doesn't cause actually cause the behavior to be
defined *unless there's an actual definition of the behavior*.

On the other other hand, the behavior is defined by the normal
semantics of calling a function.
 
A

amit.codename13

On the other hand, just because the behavior is explicitly undefined
in a certain case, that doesn't define the behavior in other cases.
The fact that the standard says the behavior is undefined in this
particular case strongly suggests that the behavior is defined in
other cases, but it doesn't cause actually cause the behavior to be
defined *unless there's an actual definition of the behavior*.

On the other other hand, the behavior is defined by the normal
semantics of calling a function.

--
Keith Thompson (The_Other_Keith) (e-mail address removed) <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"

On the other other hand, the behavior is defined by the normal
semantics of calling a function.

can you please elaborate on how the behavior is defined by the normal
semantics of calling a function?

@richard Heathfield


Does the exception *strictly* prove the rule
 
J

James Kuyper

CBFalconer said:
In other words, YES, as specified by the standard portion you
quoted.

He specified "if ... not used". The standard says "if .. used". How do
you reach the conclusion that these match?
 
A

amit.codename13

Keith Thompson said:



Right, but the behaviour *is* defined in other cases. The behaviour
of function calls *is* well-defined (given no explicit cases of
undefined behaviour). The behaviour of function returns *is*
well-defined (given no explicit cases of undefined behaviour).


In cases where the Standard makes claims of the form "If Condition A
applies, then Z is undefined", EITHER Z is well-defined (or perhaps
unspecified or implementation-defined) if not A (and if necessary
not B, C, D and any other conditions the Standard imposes
elsewhere)", OR the Standard contains a redundant redundancy.


Right.

--
Richard Heathfield <http://www.cpax.org.uk>
Email: -http://www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999

Right, but the behaviour *is* defined in other cases. The
behaviour
of function calls *is* well-defined (given no explicit cases of
undefined behaviour). The behaviour of function returns *is*
well-defined (given no explicit cases of undefined behaviour).

How is that consistent with the following from the standard?

"......or by the omission of any explicit definition of behavior."
 
K

Keith Thompson

Right, but the behaviour *is* defined in other cases. The
behaviour of function calls *is* well-defined (given no explicit
cases of undefined behaviour). The behaviour of function returns
*is* well-defined (given no explicit cases of undefined
behaviour).

How is that consistent with the following from the standard?

"......or by the omission of any explicit definition of behavior."

It's consistent because the explicit definition of behavior is not
omitted. The standard defines the behavior of an ordinary function
call. I'm not going to take the time to look up the section(s) of the
standard that do so, but consider this. If a function returns a value
and the caller uses that value, the behavior is well defined (in the
absence of any other problems). If a function returns a value and the
caller doesn't use that value, the behavior is still well defined.
The act of not returning a value doesn't cause the behavior to become
undefined; there's no need to define the behavior of something the
program *doesn't* do. The only explicit statement of undefined
behavior is when the function doesn't return a value and the caller
attempts to use it. So if a function doesn't return a value and the
caller doesn't try to use the returned value, the behavior is already
covered by other clauses of the standard.

(This is necessary to maintain compatibility with pre-ANSI C. Before
the 1989 ANSI C standard, there was no void type. A function not
intended to return a value would be declared without an explicit
return type, which would default to int. The function would not
return a value, and the caller would not attempt to use the returned
value.)
 
A

amit.codename13

It's consistent because the explicit definition of behavior is not
omitted.  The standard defines the behavior of an ordinary function
call.  I'm not going to take the time to look up the section(s) of the
standard that do so, but consider this.  If a function returns a value
and the caller uses that value, the behavior is well defined (in the
absence of any other problems).  If a function returns a value and the
caller doesn't use that value, the behavior is still well defined.
The act of not returning a value doesn't cause the behavior to become
undefined; there's no need to define the behavior of something the
program *doesn't* do.  The only explicit statement of undefined
behavior is when the function doesn't return a value and the caller
attempts to use it.  So if a function doesn't return a value and the
caller doesn't try to use the returned value, the behavior is already
covered by other clauses of the standard.

(This is necessary to maintain compatibility with pre-ANSI C.  Before
the 1989 ANSI C standard, there was no void type.  A function not
intended to return a value would be declared without an explicit
return type, which would default to int.  The function would not
return a value, and the caller would not attempt to use the returned
value.)

--
Keith Thompson (The_Other_Keith) (e-mail address removed)  <http://www.ghoti.net/~kst>
Nokia
"We must do something.  This is something.  Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"

thanks,

got it !!!
 
C

CBFalconer

Richard said:
CBFalconer said:

In other other words, NO, as specified by the Standard portion he
quoted.

Yes, I was mistaken, inasfar as the specific case mentioned is
concerned. However the code is awful, and will collapse into
undefined behaviour as soon as that function is called again, and
this time the 'result' is used.
 
C

CBFalconer

.... snip about typed functions failing to return a value ...
It's consistent because the explicit definition of behavior is
not omitted. The standard defines the behavior of an ordinary
function call. I'm not going to take the time to look up the
section(s) of the standard that do so, but consider this. If a
function returns a value and the caller uses that value, the
behavior is well defined (in the absence of any other problems).
If a function returns a value and the caller doesn't use that
value, the behavior is still well defined. The act of not
returning a value doesn't cause the behavior to become
undefined; there's no need to define the behavior of something
the program *doesn't* do. The only explicit statement of
undefined behavior is when the function doesn't return a value
and the caller attempts to use it. So if a function doesn't
return a value and the caller doesn't try to use the returned
value, the behavior is already covered by other clauses of the
standard.

(This is necessary to maintain compatibility with pre-ANSI C.
Before the 1989 ANSI C standard, there was no void type. A
function not intended to return a value would be declared
without an explicit return type, which would default to int.
The function would not return a value, and the caller would
not attempt to use the returned value.)

I fail to see where declaring failing to return a declared return
value as undefined behaviour would have fouled pre-ANSI C
compatibility. Systems that use that ability would simply have
defined that behaviour. Systems that do such things as reserving a
stack location for the returned value could eventually fail due to
stack overflow. Etc., easing stack use. However, such a
declaration now could break existing code.
 
B

Ben Bacarisse

CBFalconer said:
... snip about typed functions failing to return a value ...

I fail to see where declaring failing to return a declared return
value as undefined behaviour would have fouled pre-ANSI C
compatibility. Systems that use that ability would simply have
defined that behaviour.

Every existing implementation would have been such a system because
almost all non-trivial programs relied on this behaviour. If the C90
standard had not taken this view, almost every existing C program
would, at a stroke, have had to rely on an extension to have defined
semantics. This flies in that face of the original purpose of the
standard which was, largely, to codify existing practise.
 
K

Keith Thompson

CBFalconer said:
Keith Thompson wrote: [...]
(This is necessary to maintain compatibility with pre-ANSI C.
Before the 1989 ANSI C standard, there was no void type. A
function not intended to return a value would be declared
without an explicit return type, which would default to int.
The function would not return a value, and the caller would
not attempt to use the returned value.)

I fail to see where declaring failing to return a declared return
value as undefined behaviour would have fouled pre-ANSI C
compatibility. Systems that use that ability would simply have
defined that behaviour. Systems that do such things as reserving a
stack location for the returned value could eventually fail due to
stack overflow. Etc., easing stack use. However, such a
declaration now could break existing code.

Consider the following valid K&R C program:

#include <stdio.h>

greet(s)
char *s;
{
printf("Hello, %s\n", s);
}

main()
{
greet("world");
}

The greet() function has an implicit return type of int, but the
intent is that it doesn't return a value and the caller doesn't
attempt to use any returned value. This was extremely common practice
prior to the introduction of "void" in ANSI C89. If, as you suggest,
ANSI had declared that failing to return a value invokes undefined
behavior, this program would have been broken -- as would most
existing pre-ANSI code.
 
C

CBFalconer

Keith said:
CBFalconer said:
Keith Thompson wrote: [...]
(This is necessary to maintain compatibility with pre-ANSI C.
Before the 1989 ANSI C standard, there was no void type. A
function not intended to return a value would be declared
without an explicit return type, which would default to int.
The function would not return a value, and the caller would
not attempt to use the returned value.)

I fail to see where declaring failing to return a declared return
value as undefined behaviour would have fouled pre-ANSI C
compatibility. Systems that use that ability would simply have
defined that behaviour. Systems that do such things as reserving a
stack location for the returned value could eventually fail due to
stack overflow. Etc., easing stack use. However, such a
declaration now could break existing code.

Consider the following valid K&R C program:

#include <stdio.h>

greet(s)
char *s;
{
printf("Hello, %s\n", s);
}

main()
{
greet("world");
}

The greet() function has an implicit return type of int, but the
intent is that it doesn't return a value and the caller doesn't
attempt to use any returned value. This was extremely common practice
prior to the introduction of "void" in ANSI C89. If, as you suggest,
ANSI had declared that failing to return a value invokes undefined
behavior, this program would have been broken -- as would most
existing pre-ANSI code.

But my point is that it would have been running on the same (or
successor) system. Just as we now run C programs on POSIX systems,
we could run that on X systems, without error. Problems only arise
when we try to port it to another system. I don't think anybody
ever tried to claim that C89 could run all old K&R I programs
unmodified.

Do you disagree with that?
 
K

Keith Thompson

CBFalconer said:
Keith said:
CBFalconer said:
Keith Thompson wrote: [...]
(This is necessary to maintain compatibility with pre-ANSI C.
Before the 1989 ANSI C standard, there was no void type. A
function not intended to return a value would be declared
without an explicit return type, which would default to int.
The function would not return a value, and the caller would
not attempt to use the returned value.)

I fail to see where declaring failing to return a declared return
value as undefined behaviour would have fouled pre-ANSI C
compatibility. Systems that use that ability would simply have
defined that behaviour. Systems that do such things as reserving a
stack location for the returned value could eventually fail due to
stack overflow. Etc., easing stack use. However, such a
declaration now could break existing code.

Consider the following valid K&R C program:

#include <stdio.h>

greet(s)
char *s;
{
printf("Hello, %s\n", s);
}

main()
{
greet("world");
}

The greet() function has an implicit return type of int, but the
intent is that it doesn't return a value and the caller doesn't
attempt to use any returned value. This was extremely common practice
prior to the introduction of "void" in ANSI C89. If, as you suggest,
ANSI had declared that failing to return a value invokes undefined
behavior, this program would have been broken -- as would most
existing pre-ANSI code.

But my point is that it would have been running on the same (or
successor) system. Just as we now run C programs on POSIX systems,
we could run that on X systems, without error. Problems only arise
when we try to port it to another system. I don't think anybody
ever tried to claim that C89 could run all old K&R I programs
unmodified.

Do you disagree with that?

Certainly not *all* pre-ANSI programs can be run under C89, but the
ANSI committee went to a great deal of effort to maintain backward
compatibility. The intent was that any reasonably portable pre-ANSI
program would continue to work, with the same behavior, under C89.
The language is full of features that exist only to meet that goal.

I believe the program above would have worked properly on any pre-ANSI
implementation. The committee was careful to avoid any changes that
would break such programs. Saying that a program in which a function
fails to return a value and no caller attempts to use the returned
value invokes undefined behavior would have broken existing portable
code, and that would have been unacceptable.
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,744
Messages
2,569,483
Members
44,902
Latest member
Elena68X5

Latest Threads

Top