Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > C Test Incorrectly Uses printf() - Please Confirm

Reply
Thread Tools

C Test Incorrectly Uses printf() - Please Confirm

 
 
Martin O'Brien
Guest
Posts: n/a
 
      08-08-2010
I took an online C test a few months ago. I actually thought the test
was better than some I've taken, but one question in particular I
think has the wrong answer. The question is this:

What is printed:

int a = 1;
printf("%d", ++a, a + 5);

a. 1
b. 2
c. 7
d. undefined

I selected d. This is the explanation given as to why b is the correct
answer.

The first expression in the parameter list following the format
string is paired with the first (and only) conversion specification.
The increment is a prefix so the result of the operation is the a + 1.
Since there are more items in the value list than there are conversion
specifications, the extra value is not shown.

I believe the correct answer is d because according to K&R2 (and by
implication the Standard) the order in which function arguments are
evaluated is not defined; in fact, K&R2's example, in Section 2.12,
shows the variable n being used twice in the same printf call (albeit
with the correct number of conversion specifications).

Am I correct that d is the correct answer?

--
Martin
 
Reply With Quote
 
 
 
 
Malcolm McLean
Guest
Posts: n/a
 
      08-08-2010
On Aug 8, 9:55*pm, "Martin O'Brien" <(E-Mail Removed)> wrote:
>
> * *int a = 1;
> * *printf("%d", ++a, a + 5);
>
> * *a. 1
> * *b. 2
> * *c. 7
> * *d. undefined


> Am I correct that d is the correct answer?
>

I'm pretty sure you're right. But the important thing is it doesn't
really matter. It's not clear what the value of a + 5 should be, or is
intended by the programmer, so the construct is unusable. It may be
implementation-defined rather than undefined, but that leads us into
inappropriate thumbing through the footnotes of the standard, and is
something only a compiler writer should do.


 
Reply With Quote
 
 
 
 
Shao Miller
Guest
Posts: n/a
 
      08-08-2010
Martin O'Brien wrote:
> I took an online C test a few months ago. I actually thought the test
> was better than some I've taken, but one question in particular I
> think has the wrong answer. The question is this:
>
> What is printed:
>
> int a = 1;
> printf("%d", ++a, a + 5);
>
> a. 1
> b. 2
> c. 7
> d. undefined
>
> I selected d. This is the explanation given as to why b is the correct
> answer.

What about (b)? There is a sequence point before the function 'printf'
is called, so '++a' has finished being evaluated and has modified the
value of 'a'. 'a + 5' is also evaluated, but the format string doesn't
use that argument. 'a + 5' does not attempt to modify the value of 'a'.
> ... ... ...

 
Reply With Quote
 
Shao Miller
Guest
Posts: n/a
 
      08-08-2010
Shao Miller wrote:
> Martin O'Brien wrote:
>> I took an online C test a few months ago. I actually thought the test
>> was better than some I've taken, but one question in particular I
>> think has the wrong answer. The question is this:
>>
>> What is printed:
>>
>> int a = 1;
>> printf("%d", ++a, a + 5);
>>
>> a. 1
>> b. 2
>> c. 7
>> d. undefined
>>
>> I selected d. This is the explanation given as to why b is the correct
>> answer.

> What about (b)? There is a sequence point before the function 'printf'
> is called, so '++a' has finished being evaluated and has modified the
> value of 'a'. 'a + 5' is also evaluated, but the format string doesn't
> use that argument. 'a + 5' does not attempt to modify the value of 'a'.
>> ... ... ...

As in, the second argument has a definite value at least by the time of
the function call. So does the third argument have a value. It doesn't
matter whether the third argument's value is 6 or 7, because the format
string doesn't use it. Thus '2' is printed.

If the question instead asked, "What will be the value passed as the
third argument?" I would guess (d). But the order in which these
arguments are evaluated cannot impact what value is passed as the second
argument; the only one to be printed.
 
Reply With Quote
 
bert
Guest
Posts: n/a
 
      08-08-2010
On 8 Aug, 19:55, "Martin O'Brien" <(E-Mail Removed)> wrote:
> I took an online C test a few months ago. I actually thought the test
> was better than some I've taken, but one question in particular I
> think has the wrong answer. The question is this:
>
> * *What is printed:
>
> * *int a = 1;
> * *printf("%d", ++a, a + 5);
>
> * *a. 1
> * *b. 2
> * *c. 7
> * *d. undefined
>
> I selected d. This is the explanation given as to why b is the correct
> answer.
>
> * *The first expression in the parameter list following the format
> string is paired with the first (and only) conversion specification.
> The increment is a prefix so the result of the operation is the a + 1.
> Since there are more items in the value list than there are conversion
> specifications, the extra value is not shown.
>
> I believe the correct answer is d because according to K&R2 (and by
> implication the Standard) the order in which function arguments are
> evaluated is not defined; in fact, K&R2's example, in Section 2.12,
> shows the variable n being used twice in the same printf call (albeit
> with the correct number of conversion specifications).
>
> Am I correct that d is the correct answer?
>
> --
> Martin


No, the correct answer is (b). Answer (d)
would apply where the printf arguments were
the other way round.

The argument "++a" evaluates to 2, whether
it is evaluated before "a + 5" or after it.

The argument "a + 5" is likely to evaluate
to either 6 or 7, depending on whether it is
evaluated before or after "++a". The standard
may well allow its evaluation to be undefined,
because of the ++a (I'm no standards expert)
but as the argument isn't printed, it doesn't
matter.

However: that printf format string does not
have a new line character, so the output
will not appear at once; and there have
been implementations of printf which
assumed that their parameter count matched
the number of fields in the format string,
and caused a stack fault if it didn't; in
which case the answer would be (e) nothing.
--
 
Reply With Quote
 
Ersek, Laszlo
Guest
Posts: n/a
 
      08-08-2010
On Sun, 8 Aug 2010, Martin O'Brien wrote:

> I took an online C test a few months ago. I actually thought the test
> was better than some I've taken, but one question in particular I think
> has the wrong answer. The question is this:
>
> What is printed:
>
> int a = 1;
> printf("%d", ++a, a + 5);
>
> a. 1
> b. 2
> c. 7
> d. undefined
>
> I selected d. This is the explanation given as to why b is the correct
> answer.
>
> The first expression in the parameter list following the format string
> is paired with the first (and only) conversion specification. The
> increment is a prefix so the result of the operation is the a + 1. Since
> there are more items in the value list than there are conversion
> specifications, the extra value is not shown.
>
> I believe the correct answer is d because according to K&R2 (and by
> implication the Standard) the order in which function arguments are
> evaluated is not defined; in fact, K&R2's example, in Section 2.12,
> shows the variable n being used twice in the same printf call (albeit
> with the correct number of conversion specifications).
>
> Am I correct that d is the correct answer?


Yes, but I believe not for the reason you mention.

C99 6.5.2.2 Function calls, p10:

"The order of evaluation of the function designator, the actual arguments,
and subexpressions within the actual arguments is unspecified, but there
is a sequence point before the actual call."

So the order of evaluation is unspecified, not undefined. However,

C99 6.5 Expressions, p2:

"Between the previous and next sequence point an object shall have its
stored value modified at most once by the evaluation of an expression.
Furthermore, the prior value shall be read only to determine the value to
be stored."

Here are the sequence points:

> int a = 1;


SP#1 at semicolon.

> printf(
> "%d", ++a, a + 5


SP#2 after "printf" (the function designator) and all arguments have been
evaluated (in unspecified order), right before printf() is entered.

> );


SP#3 at semicolon.

"a" is read twice and written once between SP#1 and SP#2. The expression
"a+5" reads "a" *not* in order to determine "a"'s next value, so 6.5p2 is
violated. Hence the undefined behavior.

(In practice, compilers need 6.5p2 so that they can reliably order
store/load operations between adjacent sequence points along data
dependency edges. If no such dependency is found, they can choose whatever
order. They can even overlap/interleave such simple expressions as ++a and
a+5 -- not function calls though.)

Under this aspect, it is irrelevant that the value of a+5 will be "thrown
away" anyway. C's eval is eager (see 6.5.2.2p10 above, for example), not
lazy.

lacos

--
All content in this message, posted from <(E-Mail Removed)>, is my
personal opinion, representing noone else than myself.
 
Reply With Quote
 
Eric Sosman
Guest
Posts: n/a
 
      08-08-2010
On 8/8/2010 2:55 PM, Martin O'Brien wrote:
> I took an online C test a few months ago. I actually thought the test
> was better than some I've taken, but one question in particular I
> think has the wrong answer. The question is this:
>
> What is printed:
>
> int a = 1;
> printf("%d", ++a, a + 5);
>
> a. 1
> b. 2
> c. 7
> d. undefined
>
> I selected d. This is the explanation given as to why b is the correct
> answer.


You were right.

> The first expression in the parameter list following the format
> string is paired with the first (and only) conversion specification.
> The increment is a prefix so the result of the operation is the a + 1.
> Since there are more items in the value list than there are conversion
> specifications, the extra value is not shown.


The explanation is wrong. The undefined behavior arises from the
lack of a sequence point between ++a and a+5, before printf() even
begins to execute. It doesn't matter that the value (if any) of a+5
won't be used; the behavior is undefined anyhow.

Ponder this one:

printf ("%d\n", ++a, strlen(NULL));

The fact that the printf() will not use its third parameter does not
mean that the third argument's undefined behavior is forgiven.

> I believe the correct answer is d because according to K&R2 (and by
> implication the Standard) the order in which function arguments are
> evaluated is not defined; in fact, K&R2's example, in Section 2.12,
> shows the variable n being used twice in the same printf call (albeit
> with the correct number of conversion specifications).
>
> Am I correct that d is the correct answer?


Yes.

--
Eric Sosman
http://www.velocityreviews.com/forums/(E-Mail Removed)lid
 
Reply With Quote
 
Willem
Guest
Posts: n/a
 
      08-08-2010
Shao Miller wrote:
) As in, the second argument has a definite value at least by the time of
) the function call. So does the third argument have a value. It doesn't
) matter whether the third argument's value is 6 or 7, because the format
) string doesn't use it. Thus '2' is printed.

It's undefined behaviour. Anything can happen.
'2' is not *guaranteed*.

I agree, it's extremely unlikely to be anything else.
Probably no system exists where it would not print 2.
But pedantically speaking, the result *is* undefined.

But in some theoretical machine, it could fail.
(For example, the instructions for reading in a+5 and writing in a++
could be parallelized into the same slot, and the simultaneous read
and write could cause some kind of signal to be raised.)


SaSW, Willem
--
Disclaimer: I am in no way responsible for any of the statements
made in the above text. For all I know I might be
drugged or something..
No I'm not paranoid. You all think I'm paranoid, don't you !
#EOT
 
Reply With Quote
 
Keith Thompson
Guest
Posts: n/a
 
      08-08-2010
Malcolm McLean <(E-Mail Removed)> writes:
> On Aug 8, 9:55*pm, "Martin O'Brien" <(E-Mail Removed)> wrote:
>> * *int a = 1;
>> * *printf("%d", ++a, a + 5);
>>
>> * *a. 1
>> * *b. 2
>> * *c. 7
>> * *d. undefined

>
>> Am I correct that d is the correct answer?
>>

> I'm pretty sure you're right. But the important thing is it doesn't
> really matter. It's not clear what the value of a + 5 should be, or is
> intended by the programmer, so the construct is unusable. It may be
> implementation-defined rather than undefined, but that leads us into
> inappropriate thumbing through the footnotes of the standard, and is
> something only a compiler writer should do.


The standard is not intended only for compiler writers. It is, in
effect, a contract between implementers and programmers; as such,
both implementers and programmers can benefit from being familiar
with it.

In practice, the fact that the presented code is ugly and should
never pass a code review, whether its behavior is defined or not,
may be more important than the reasons why its behavior is undefined.
But I'd be interested in knowing why you think that reading the
standard (and no, footnotes aren't relevant here) is "something
only a compiler writer should do.".

--
Keith Thompson (The_Other_Keith) (E-Mail 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"
 
Reply With Quote
 
Shao Miller
Guest
Posts: n/a
 
      08-08-2010
Ersek, Laszlo wrote:
> On Sun, 8 Aug 2010, Martin O'Brien wrote:
>
>> I took an online C test a few months ago. I actually thought the test
>> was better than some I've taken, but one question in particular I
>> think has the wrong answer. The question is this:
>>
>> What is printed:
>>
>> int a = 1;
>> printf("%d", ++a, a + 5);
>>
>> a. 1
>> b. 2
>> c. 7
>> d. undefined
>>
>> I selected d. This is the explanation given as to why b is the correct
>> answer.
>>
>> The first expression in the parameter list following the format
>> string is paired with the first (and only) conversion specification.
>> The increment is a prefix so the result of the operation is the a + 1.
>> Since there are more items in the value list than there are conversion
>> specifications, the extra value is not shown.
>>
>> I believe the correct answer is d because according to K&R2 (and by
>> implication the Standard) the order in which function arguments are
>> evaluated is not defined; in fact, K&R2's example, in Section 2.12,
>> shows the variable n being used twice in the same printf call (albeit
>> with the correct number of conversion specifications).
>>
>> Am I correct that d is the correct answer?

>
> Yes, but I believe not for the reason you mention.
>
> C99 6.5.2.2 Function calls, p10:
>
> "The order of evaluation of the function designator, the actual
> arguments, and subexpressions within the actual arguments is
> unspecified, but there is a sequence point before the actual call."
>
> So the order of evaluation is unspecified, not undefined. However,
>
> C99 6.5 Expressions, p2:
>
> "Between the previous and next sequence point an object shall have its
> stored value modified at most once by the evaluation of an expression.
> Furthermore, the prior value shall be read only to determine the value
> to be stored."
>
> Here are the sequence points:
>
>> int a = 1;

>
> SP#1 at semicolon.
>
>> printf(
>> "%d", ++a, a + 5

>
> SP#2 after "printf" (the function designator) and all arguments have
> been evaluated (in unspecified order), right before printf() is entered.
>
>> );

>
> SP#3 at semicolon.
>
> "a" is read twice and written once between SP#1 and SP#2. The expression
> "a+5" reads "a" *not* in order to determine "a"'s next value, so 6.5p2
> is violated. Hence the undefined behavior.
>
> (In practice, compilers need 6.5p2 so that they can reliably order
> store/load operations between adjacent sequence points along data
> dependency edges. If no such dependency is found, they can choose
> whatever order. They can even overlap/interleave such simple expressions
> as ++a and a+5 -- not function calls though.)
>
> Under this aspect, it is irrelevant that the value of a+5 will be
> "thrown away" anyway. C's eval is eager (see 6.5.2.2p10 above, for
> example), not lazy.

Whoa. It never occurred to me that:

int i = 1;
i = i + i;

could yield undefined behaviour due to the double-read and the single
store. Amazing! Nice one! Instead, we should use:

int i = 1;
i += i;

Because it differs from:

int i = 1;
i = i + i;

In that with the similarity between 'E1 += E2' and 'E1 = E1 + E2' in the
latter case, 'E1' is only evaluated once. But uh oh... What about 'E2'?

I suppose the only well-behaved way to do it is:

int i = 1, j;
j = i;
i = i + j;

Is that right?
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
C Test Incorrectly Uses printf() - Please Confirm Martin C Programming 4 08-10-2010 05:25 PM
Confirm my Performance Test Against Java? Ben Christensen Ruby 39 09-03-2009 05:20 AM
Please: ITemplate propery being saved incorrectly -- Attributes usage incorrect? S.Sigal ASP .Net Building Controls 0 08-14-2004 02:07 PM
Please: ITemplate propery being saved incorrectly -- Attributes usage incorrect? S.Sigal ASP .Net Web Controls 0 08-14-2004 02:04 PM
test test test test test test test Computer Support 2 07-02-2003 06:02 PM



Advertisments