Discussion:
How are function calls performed?
(too old to reply)
James R. Kuyper
2016-06-20 22:22:33 UTC
Permalink
Raw Message
... "In preparing for the call to a function, the arguments are
evaluated, and each parameter is assigned the value of the
corresponding argument."
"On entry to the function, the size expressions of each variably
modified parameter are evaluated and the value of each argument
expression is converted to the type of the corresponding parameter as
if by assignment."
The last quote confuses me - are the argument expressions available
at function entry? Besides what are those conversions that are talked
about?
The argument expressions are not available from within the function, but
they are available while preparing to call the function.

Consider the following code:

int func(unsigned short us, float f) { return f/us; }

long l = 300;
double d = 24.3;
int i = func(l*500L, d*2.0);

l*500L and d*2.0 are the argument expressions that it refers to.
When it says "the arguments are evaluated", it means that the expression
l*500L is evaluated to give a value of 150000L, and that d*2.0 is
evaluated to give a value of 48.6.

"assigned the value of the corresponding argument" means that func()
behaves as if the following two lines were executed before the start of
the program:

us = 150000L;
f = 48.6;

"converted to the type of the corresponding parameter as if by
assignment" is made very clear in the above code, because I've
re-written it "as if by assignment". The value 150000L has the type
'long', while 'us' has the type 'unsigned short'. This means that
150000L must be converted to "unsigned short" before saving the value in
'us'. If USHRT_MAX has a value of 65535, then conversion to unsigned
short involves subtracting 65536 from 150000L twice, giving a value of
18928.

Similarly, 48.6 has the type double, while 'f' has the type float, so
48.6 has to be converted to type float. The conversion will generally
result in a small change in the value: the double constant 24.3 cannot
be represented exactly unless FLT_RADIX is an integer multiple of 10.
The actual value of that constant will be either the largest
representable double that is less than 24.3, or the smallest
representable double that is greater than 24.3. When d*2.0 is converted
to float, it will, at best, be converted to either the largest
representable float that is smaller than the double value, or the
smallest representable float that is larger than the double value. In
general, this will not be precisely the same value as d*2.0.
s***@gmail.com
2016-06-20 22:32:01 UTC
Permalink
Raw Message
Post by James R. Kuyper
... "In preparing for the call to a function, the arguments are
evaluated, and each parameter is assigned the value of the
corresponding argument."
"On entry to the function, the size expressions of each variably
modified parameter are evaluated and the value of each argument
expression is converted to the type of the corresponding parameter as
if by assignment."
The last quote confuses me - are the argument expressions available
at function entry? Besides what are those conversions that are talked
about?
The argument expressions are not available from within the function, but
they are available while preparing to call the function.
int func(unsigned short us, float f) { return f/us; }
long l = 300;
double d = 24.3;
int i = func(l*500L, d*2.0);
l*500L and d*2.0 are the argument expressions that it refers to.
When it says "the arguments are evaluated", it means that the expression
l*500L is evaluated to give a value of 150000L, and that d*2.0 is
evaluated to give a value of 48.6.
"assigned the value of the corresponding argument" means that func()
behaves as if the following two lines were executed before the start of
us = 150000L;
f = 48.6;
"converted to the type of the corresponding parameter as if by
assignment" is made very clear in the above code, because I've
re-written it "as if by assignment". The value 150000L has the type
'long', while 'us' has the type 'unsigned short'. This means that
150000L must be converted to "unsigned short" before saving the value in
'us'. If USHRT_MAX has a value of 65535, then conversion to unsigned
short involves subtracting 65536 from 150000L twice, giving a value of
18928.
Similarly, 48.6 has the type double, while 'f' has the type float, so
48.6 has to be converted to type float. The conversion will generally
result in a small change in the value: the double constant 24.3 cannot
be represented exactly unless FLT_RADIX is an integer multiple of 10.
The actual value of that constant will be either the largest
representable double that is less than 24.3, or the smallest
representable double that is greater than 24.3. When d*2.0 is converted
to float, it will, at best, be converted to either the largest
representable float that is smaller than the double value, or the
smallest representable float that is larger than the double value. In
general, this will not be precisely the same value as d*2.0.
I have the feeling that this paragraph (the last one I quoted) doesn't add up anything new to the wording in 6.5.2.2 "Function calls" which is also way more clear. Correct me if I'm wrong?
s***@gmail.com
2016-06-20 22:34:04 UTC
Permalink
Raw Message
Post by s***@gmail.com
Post by James R. Kuyper
... "In preparing for the call to a function, the arguments are
evaluated, and each parameter is assigned the value of the
corresponding argument."
"On entry to the function, the size expressions of each variably
modified parameter are evaluated and the value of each argument
expression is converted to the type of the corresponding parameter as
if by assignment."
The last quote confuses me - are the argument expressions available
at function entry? Besides what are those conversions that are talked
about?
The argument expressions are not available from within the function, but
they are available while preparing to call the function.
int func(unsigned short us, float f) { return f/us; }
long l = 300;
double d = 24.3;
int i = func(l*500L, d*2.0);
l*500L and d*2.0 are the argument expressions that it refers to.
When it says "the arguments are evaluated", it means that the expression
l*500L is evaluated to give a value of 150000L, and that d*2.0 is
evaluated to give a value of 48.6.
"assigned the value of the corresponding argument" means that func()
behaves as if the following two lines were executed before the start of
us = 150000L;
f = 48.6;
"converted to the type of the corresponding parameter as if by
assignment" is made very clear in the above code, because I've
re-written it "as if by assignment". The value 150000L has the type
'long', while 'us' has the type 'unsigned short'. This means that
150000L must be converted to "unsigned short" before saving the value in
'us'. If USHRT_MAX has a value of 65535, then conversion to unsigned
short involves subtracting 65536 from 150000L twice, giving a value of
18928.
Similarly, 48.6 has the type double, while 'f' has the type float, so
48.6 has to be converted to type float. The conversion will generally
result in a small change in the value: the double constant 24.3 cannot
be represented exactly unless FLT_RADIX is an integer multiple of 10.
The actual value of that constant will be either the largest
representable double that is less than 24.3, or the smallest
representable double that is greater than 24.3. When d*2.0 is converted
to float, it will, at best, be converted to either the largest
representable float that is smaller than the double value, or the
smallest representable float that is larger than the double value. In
general, this will not be precisely the same value as d*2.0.
I have the feeling that this paragraph (the last one I quoted) doesn't add up anything new to the wording in 6.5.2.2 "Function calls" which is also way more clear. Correct me if I'm wrong?
In-fact I find it redundant.
James R. Kuyper
2016-06-20 23:03:13 UTC
Permalink
Raw Message
...
Post by s***@gmail.com
"On entry to the function, the size expressions of each variably
modified parameter are evaluated and the value of each argument
expression is converted to the type of the corresponding parameter as
if by assignment."
The last quote confuses me - are the argument expressions available
at function entry? Besides what are those conversions that are talked
about?
...
Post by s***@gmail.com
I have the feeling that this paragraph (the last one I quoted)
doesn't add up anything new to the wording in 6.5.2.2 "Function calls" which is
also way more clear. Correct me if I'm wrong?
Well, 6.5.2.2 says nothing about the size expressions for variably
modified parameters, so that part, at least, is not redundant.

However, I agree that 6.5.2.2p4's assertion that the argument values are
assigned to the parameters inherently implies that those values should
be "converted ... as if by assignment", so that part does seem to be
redundant. I may be missing some subtle point here; if so, I'm sure
someone else will point it out.
Kaz Kylheku
2016-06-20 23:22:55 UTC
Permalink
Raw Message
Post by James R. Kuyper
...
Post by s***@gmail.com
"On entry to the function, the size expressions of each variably
modified parameter are evaluated and the value of each argument
expression is converted to the type of the corresponding parameter as
if by assignment."
The last quote confuses me - are the argument expressions available
at function entry? Besides what are those conversions that are talked
about?
...
Post by s***@gmail.com
I have the feeling that this paragraph (the last one I quoted)
doesn't add up anything new to the wording in 6.5.2.2 "Function calls" which is
also way more clear. Correct me if I'm wrong?
Well, 6.5.2.2 says nothing about the size expressions for variably
modified parameters, so that part, at least, is not redundant.
It's not merely redundant; it's incorrect and contradictory. Argument
expressions are evaluated before entry into the function, not on entry.
What enters a function are the argument values.

When function calls cross translation units, it is clear that the
evaluation of argument expressions takes place in the calling
translation unit, and the initialization of parameters (including
the evaluation of the size expressions of variably-modified
parameters) is in the called translation unit.

A given function can be called from many places, each using completely
different expressions. It knows nothing about those expressions.
s***@gmail.com
2016-06-22 05:33:58 UTC
Permalink
Raw Message
Post by Kaz Kylheku
Post by James R. Kuyper
...
Post by s***@gmail.com
"On entry to the function, the size expressions of each variably
modified parameter are evaluated and the value of each argument
expression is converted to the type of the corresponding parameter as
if by assignment."
The last quote confuses me - are the argument expressions available
at function entry? Besides what are those conversions that are talked
about?
...
Post by s***@gmail.com
I have the feeling that this paragraph (the last one I quoted)
doesn't add up anything new to the wording in 6.5.2.2 "Function calls" which is
also way more clear. Correct me if I'm wrong?
Well, 6.5.2.2 says nothing about the size expressions for variably
modified parameters, so that part, at least, is not redundant.
It's not merely redundant; it's incorrect and contradictory. Argument
expressions are evaluated before entry into the function, not on entry.
What enters a function are the argument values.
When function calls cross translation units, it is clear that the
evaluation of argument expressions takes place in the calling
translation unit, and the initialization of parameters (including
the evaluation of the size expressions of variably-modified
parameters) is in the called translation unit.
A given function can be called from many places, each using completely
different expressions. It knows nothing about those expressions.
How it made it to the standard paper then? Should we consider submitting a Defect report?
James R. Kuyper
2016-06-22 17:23:35 UTC
Permalink
Raw Message
On 06/22/2016 01:33 AM, ***@gmail.com wrote:
...
Post by s***@gmail.com
How it made it to the standard paper then? Should we consider submitting a Defect report?
Only members of the committee can submit a defect report - what
outsiders can do is try to convince one of the committee members to
submit one (or, you could try to join the committee - it's a volunteer
organization, they're generally open to accepting new volunteers). It
used to be that we had a few actual committee members monitoring this
newsgroup, but it's been quite a while since the last time I saw a
message posted by anyone I knew to be a committee member.

The members of the ISO are actually entire organizations, one for each
country, such as ANSI for the US; the human members of the C committee
are actually representatives of one those organizations. If you're
interested, you should contact the organization in your country that is
a member of ISO, but if your country's standards organization isn't a
member, you can probably contact ANSI - they don't restrict membership
to US citizens, so I doubt that they would care about US citizenship
when accepting a comment.

I once found a list of the human members of the C committee, but I can't
find it anymore. You might be able to find something by contacting one
of the people on the committee's contacts page:
<http://www.open-std.org/jtc1/sc22/wg14/www/contacts>.

Loading...