C return a++ - is it safe?

J

James Harris

Consider how the return statement is defined: the expression is
evaluated, and the result is returned. Updating ``a'' is part of the
evaluation of the expression.

Is there some particular reason you're concerned that a compiler might
handle something this simple incorrectly?

In any context other than a return statement
mov eax, a
{use eax}
inc eax

So in a return statement
mov eax, a
ret
inc eax

which, of course, is wrong so the compiler should handle two special
cases:

1. return a++; where a is automatic
mov eax, a
ret
/* ignore the ++ */

2. return a++; where a persists
mov eax, a
mov ebx, eax
inc ebx
mov a, ebx
ret
 
D

Dik T. Winter

> All software (including compilers) has bugs. All software should be
> thoroughly tested. But a compiler bug in the handling of ``return
> a++;'' is quite low on the list of things I'd worry about -- higher
> than ``1 + 1 == 2'', lower than, say, some obscure C99 feature, and
> about the same as ``return (a = 42);''.

You would be surprised at the bugs I have seen in compilers and
assemblers. It ranges from blatant errors in something akin to
include files (wrong values all over the place for floating point
attributes in the DG Ada compiler) to issuing the wrong opcode
for a particular inxtruction (a Gould assembler).
 
J

James Kuyper

Tor said:
Chris Hills wrote:

[...]
Regardless of the standard(s) I think this is one you would need to
empirically test of the compiler(s) in question.

If this were Ada one could just refer to the standard but it's C and
nothing is guaranteed.

Well, some C compilers has been validated:

http://www.peren.com/pages/cvsa_set.htm
http://www.plumhall.com/stec.html

and at this point, the C90 test cases should detect such an compiler
bug. However, in safety-critical SW, I wouldn't advocate using construct
like

return a++;

I'm sorry - but if you have a compiler you can't trust to handle 'return
a++;' correctly, why are you using it, even for software that isn't
safety critical (and especially for code that is)? If there's any
significant likelihood that it might mishandle something that simple, I
most certainly wouldn't want to write anything more complicated in it.
 
K

karthikbalaguru

The above answers the query :):)
So, return statement has defined that the expression is evaluated and
the
result is returned. :):)
In any context other than a return statement
mov eax, a
{use eax}
inc eax

So in a return statement
mov eax, a
ret
inc eax

which, of course, is wrong so the compiler should handle two special
cases:

1. return a++; where a is automatic
mov eax, a
ret
/* ignore the ++ */

2. return a++; where a persists
mov eax, a
mov ebx, eax
inc ebx
mov a, ebx
ret

Interesting :):)

Karthik Balaguru
 
K

Kenneth Brody

Tor Rustad wrote:
[...]
However, in safety-critical SW, I wouldn't advocate using construct
like

return a++;

anyway.

Why not? If the compiler doesn't handle it right, then I wouldn't
trust it for the rest of the "safety-critical" program either.

However, consider:

unsigned long GetNextID(void)
{
static unsigned long ID = 1;
return ID++;
}

I suppose you could "avoid" the "bad" code by doing something like
this instead (though I would have to ask "why bother rearranging
the code"):

unsigned long GetNextID(void)
{
static unsigned long ID = 0;
ID = ID + 1; /* We can't trust "ID++". Remember? */
return ID;
}

Of course, in both cases, I suppose a check for ID == ULONG_MAX may
be in order, "just in case". (Of course, what to do in that case
depends on the specific app.)

--
+-------------------------+--------------------+-----------------------+
| Kenneth J. Brody | www.hvcomputer.com | #include |
| kenbrody/at\spamcop.net | www.fptech.com | <std_disclaimer.h> |
+-------------------------+--------------------+-----------------------+
Don't e-mail me at: <mailto:[email protected]>
 
E

Eric Sosman

Tor Rustad wrote On 10/30/07 19:06,:
[...]
However, in safety-critical SW, I wouldn't advocate using construct
like

return a++;

What's your opinion of `return getchar();'? Keep
in mind that in many implementations, getchar() is a
macro that expands to an expression with side-effects.
On an implementation I happen to have handy at the
moment, `return getchar();' produces (reformatted for
clarity)

return ( --(( &__iob[0]))->_cnt < 0
? __filbuf( (&__iob[0]) )
: (int) *(( &__iob[0]))->_ptr++ );

So, what's your verdict? Should `return getchar();'
be avoided in safety-critical software?
 
D

Dave Hansen

[...]
I believe you're missing his point. Ada has a very thorough
validation suite and stringent restrictions on what may be called
an Ada compiler. This isn't the case with C compilers; anybody
can produce what they call a C compiler. It is even possible
that there is no such thing as a fully conforming C compiler.
His point is that in the real world this is the kind of thing
that you should check whether the compiler gets it right.
Precisely

Off
hand, I would think that it is the sort of thing that a compiler
could be expected to get right but I might well be wrong.

In other words you wouldn't bet your life on it....

In that case (betting my life), Ada has no advantage over C.

"Trust, but verify."

Regards,

-=Dave
 
T

Tor Rustad

Kenneth Brody wrote:

[in addition, my response applies to Kuyper and Sosman]
Tor Rustad wrote:
[...]
However, in safety-critical SW, I wouldn't advocate using construct
like

return a++;

anyway.

Why not? If the compiler doesn't handle it right, then I wouldn't
trust it for the rest of the "safety-critical" program either.


First, I didn't agree with Chris Hills, because

1. I didn't find such a C compiler bug likely
2. If such a compiler bug existed, the unit test should detect it

My comment on not advocating returning a++, is more of a stylish matter,
since post conditions in functions, usually follow after the last
expression, and before the return statement.

Returning expressions, obfuscate debugging too.
 
M

Mark McIntyre

I'm sorry - but if you have a compiler you can't trust to handle 'return
a++;'

AFAICS, its not a question of whether the /compiler/ can handle it,
its a question of whether the programmers understand what it does. See
for instance this entire thread.

--
Mark McIntyre

"Debugging is twice as hard as writing the code in the first place.
Therefore, if you write the code as cleverly as possible, you are,
by definition, not smart enough to debug it."
--Brian Kernighan
 
J

James Kuyper

Mark said:
AFAICS, its not a question of whether the /compiler/ can handle it,
its a question of whether the programmers understand what it does. See
for instance this entire thread.

That wasn't clear from the original comment, though it is clear from one
of Tor's most recent messages. Previous messages in this sub-thread were
about testing the compiler to determine whether it implemented 'return
a++;' correctly. In that context, it is very definitely an issue of
whether or not you can trust the complier to handle it correctly.

I would estimate the a-priori likelihood that "return a++;" was
implemented incorrectly by any particular compiler to be very low. If I
started testing the features that I thought were most likely to be
incorrectly implemented, and worked my way down the list in order of
decreasing likelihood, I think I'd have a few million test cases before
I ever got around to worrying about "return a++;" For me, such thorough
testing isn't worth it; I'll wait until I see a problem, and then
complain about it. In a more safety-critical environment, where there's
lots of funds to support such testing, it might be worthwhile.
 
C

Chris Hills

CBFalconer said:
Yes. The gcc test suite is freely available. However it is geared
to "gcc C" rather than ISO std C.

OFF TOPIC :) this NG as you have REPEATEDLY told every one is for the
discussion of STANDARD C. GCC is not C it is "a C like language"
according to your oft repeated definition.

You of all people should refrain from this level of hypocrisy!

So it is NOT a C test suite.
It is a GCC build confirmation test.

Also AFAIK It falls far short of what a test suite for a compiler should
be.
See Perennial and Plum Hall for C test suites.
 
C

Chris Hills

Dave said:
[...]
I believe you're missing his point. Ada has a very thorough
validation suite and stringent restrictions on what may be called
an Ada compiler. This isn't the case with C compilers; anybody
can produce what they call a C compiler. It is even possible
that there is no such thing as a fully conforming C compiler.
His point is that in the real world this is the kind of thing
that you should check whether the compiler gets it right.
Precisely

Off
hand, I would think that it is the sort of thing that a compiler
could be expected to get right but I might well be wrong.

In other words you wouldn't bet your life on it....

In that case (betting my life), Ada has no advantage over C.

"Trust, but verify."

Regards,

-=Dave

Absolutely,.... For years I have been arguing there is no such thing as
a
"safe" language. It is all down to the quality of the implementation
 
C

Chris Hills

Tor Rustad said:
Kenneth Brody wrote:

[in addition, my response applies to Kuyper and Sosman]
Tor Rustad wrote:
[...]
However, in safety-critical SW, I wouldn't advocate using construct
like

return a++;

anyway.
Why not? If the compiler doesn't handle it right, then I wouldn't
trust it for the rest of the "safety-critical" program either.


First, I didn't agree with Chris Hills, because

1. I didn't find such a C compiler bug likely

"Likely" is not good enough. You have to be certain.
2. If such a compiler bug existed, the unit test should detect it
Absolutely.

My comment on not advocating returning a++, is more of a stylish
matter, since post conditions in functions, usually follow after the
last expression, and before the return statement.

Returning expressions, obfuscate debugging too.

I agree completely.
 
C

Chris Hills

Eric Sosman said:
Tor Rustad wrote On 10/30/07 19:06,:
[...]
However, in safety-critical SW, I wouldn't advocate using construct
like

return a++;

What's your opinion of `return getchar();'? Keep
in mind that in many implementations, getchar() is a
macro that expands to an expression with side-effects.
On an implementation I happen to have handy at the
moment, `return getchar();' produces (reformatted for
clarity)

return ( --(( &__iob[0]))->_cnt < 0
? __filbuf( (&__iob[0]) )
: (int) *(( &__iob[0]))->_ptr++ );

So, what's your verdict? Should `return getchar();'
be avoided in safety-critical software?

Personally I always prefer to just return a value.

I would

a = getchar();

return a;

It also helps of you are going to single step the C (as opposed to the
assembler) or you are doing white box unit testing.
 
K

Keith Thompson

Chris Hills said:
OFF TOPIC :) this NG as you have REPEATEDLY told every one is for the
discussion of STANDARD C. GCC is not C it is "a C like language"
according to your oft repeated definition.

You of all people should refrain from this level of hypocrisy!

So it is NOT a C test suite.
It is a GCC build confirmation test.

Also AFAIK It falls far short of what a test suite for a compiler
should be.
See Perennial and Plum Hall for C test suites.

I'm not familiar with the gcc test suite, but since gcc attempts to
conform to C90 and/or C95 in certain modes, I would assume that the
test suite would, among other things, test that conformance.
 
K

Keith Thompson

Chris Hills said:
Eric Sosman said:
Tor Rustad wrote On 10/30/07 19:06,:
[...]
However, in safety-critical SW, I wouldn't advocate using construct
like

return a++;

What's your opinion of `return getchar();'? Keep
in mind that in many implementations, getchar() is a
macro that expands to an expression with side-effects.
On an implementation I happen to have handy at the
moment, `return getchar();' produces (reformatted for
clarity)

return ( --(( &__iob[0]))->_cnt < 0
? __filbuf( (&__iob[0]) )
: (int) *(( &__iob[0]))->_ptr++ );

So, what's your verdict? Should `return getchar();'
be avoided in safety-critical software?

Personally I always prefer to just return a value.

I would

a = getchar();

return a;

Ok, that's fine -- but a compiler that mishandles ``return <expr>''
would be nearly as likely to mishandle ``a = <expr>''.

I just don't see that there's any significant need to worry more about
``return a++;'' than about any other straightforward language
construct.

If you think that something like:
result = a++;
return result;
is better style than
return a++;
I won't necessarily argue -- but either form calls for exactly the
same amount of testing.
 
K

Keith Thompson

Chris Hills said:
Tor Rustad said:
Kenneth Brody wrote:

[in addition, my response applies to Kuyper and Sosman]
Tor Rustad wrote:
[...]
However, in safety-critical SW, I wouldn't advocate using construct
like

return a++;

anyway.
Why not? If the compiler doesn't handle it right, then I wouldn't
trust it for the rest of the "safety-critical" program either.


First, I didn't agree with Chris Hills, because

1. I didn't find such a C compiler bug likely

"Likely" is not good enough. You have to be certain.

What a pity that certainty is not possible.
 

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

Staff online

Members online

Forum statistics

Threads
473,766
Messages
2,569,569
Members
45,045
Latest member
DRCM

Latest Threads

Top