Function calls that aren't evaluated

  • Thread starter Johannes Schaub (litb)
  • Start date
J

Johannes Schaub (litb)

It just happens we are discussing the following:

void f();

void g(int x) {
if(x < 0)
f(x);
else
f(x, x);
}

void f(int x) { }

int main() { f(-1); }

Has this program defined behavior? Name-lookup for "f" necessarily happens
and constructs an expression f that has no prototype. A well defined program
cannot both calls to the same function with different argument numbers if
the function has no prototype so far.

The rule is 6.5.2.2/6: "If the number of arguments does not equal the number
of parameters, the behavior is undefined."

Intuitively I would say that behavior is defined in our case because the
other branch is not evaluated. But how can we conclude this is a formal
manner from the wording?

Thanks for all your insight.
 
E

Eric Sosman

It just happens we are discussing the following:

void f();

void g(int x) {
if(x< 0)
f(x);
else
f(x, x);
}

void f(int x) { }

int main() { f(-1); }

Has this program defined behavior? Name-lookup for "f" necessarily happens
and constructs an expression f that has no prototype. A well defined program
cannot both calls to the same function with different argument numbers if
the function has no prototype so far.

The rule is 6.5.2.2/6: "If the number of arguments does not equal the number
of parameters, the behavior is undefined."

Intuitively I would say that behavior is defined in our case because the
other branch is not evaluated. But how can we conclude this is a formal
manner from the wording?

I guess it depends on how much formality you desire. The Standard
does not say that your code has undefined behavior, but neither does it
say that the behavior is defined. This may seem discouraging, but
consider: If you remove the problematic "else f(x,x);" the Standard
*still* doesn't say explicitly that the behavior is defined. I think
you have to be willing to take some things on faith.

Back to the code: It seems akin to the widely-used practice of
storing pointers to disparate functions in an array of identical
function pointer types, then plucking them out and casting as needed
when called. The fact that the code has a path that could lead to a
function being called through a pointer of the wrong type is not a
problem, as long as that path is never followed. That's the case in
your code: A problem path exists, but is not used; I see no fundamental
difference between the two situations.
 
P

Peter Nilsson

Eric Sosman said:
I guess it depends on how much formality you desire.
The Standard does not say that your code has undefined
behavior, but neither does it say that the behavior is
defined. This may seem discouraging, but consider: If you
remove the problematic "else f(x,x);" the Standard *still*
doesn't say explicitly that the behavior is defined. ...

Beyond the 'undefined return status' returned to the host
under C90, what possible behaviour can the code, with or
without else, have?
Back to the code: It seems akin to the widely-used
practice of storing pointers to disparate functions in an
array of identical function pointer types, then plucking
them out and casting as needed when called. The fact that
the code has a path that could lead to a function being
called through a pointer of the wrong type is not a problem,
as long as that path is never followed. That's the case in
your code: A problem path exists, but is not used; I see no
fundamental difference between the two situations.

Consider the similar...

int f(int x)
{
if (x == 0) return 1;
else return 1 / x;
}

The call f(0) is fine because 1/x is never evaluated, despite
6.5.5p5 saying division by zero is undefined.
 
K

Keith Thompson

Johannes Schaub (litb) said:
It just happens we are discussing the following:

void f();

void g(int x) {
if(x < 0)
f(x);
else
f(x, x);
}

void f(int x) { }

int main() { f(-1); }

Has this program defined behavior? Name-lookup for "f" necessarily happens
and constructs an expression f that has no prototype. A well defined program
cannot both calls to the same function with different argument numbers if
the function has no prototype so far.

The rule is 6.5.2.2/6: "If the number of arguments does not equal the number
of parameters, the behavior is undefined."

Intuitively I would say that behavior is defined in our case because the
other branch is not evaluated. But how can we conclude this is a formal
manner from the wording?

That paragraph is part of the section describing the semantics of a
function call. It's the behavior of the function call, something
that happens during execution, that's undefined if the number of
arguments doesn't match the number of parameters. If the function
is not called, there's nothing for the statement that "the behavior
is undefined" to apply to.

Similarly, the same section says that the arguments evaluated,
something that only happens when the function call call expression
is actually executed.

(Interestingly, I don't see an explicit statement that evaluating a
function call causes the function to be executed. A lot of things
don't make sense without that assumption, of course.)
 
T

Tim Rentsch

Keith Thompson said:
[...discussing evaluation of function calls...]

(Interestingly, I don't see an explicit statement that evaluating a
function call causes the function to be executed. A lot of things
don't make sense without that assumption, of course.)

I conjecture that the effect implied in "making a function call"
is supplied by some definition(s) in the normative reference
ISO/IEC 2382-1:1993. Note that all that is missing is a control
transfer to the function being called; once control gets there,
6.9.1p{10,11,12} do say that the function body is executed. I
don't have a copy of 2382-1 handy -- maybe someone who does can
look this up.
 

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,769
Messages
2,569,579
Members
45,053
Latest member
BrodieSola

Latest Threads

Top