Re: Does this program exhibit undefined behaviour or output?
- From: Keith Thompson <kst-u@xxxxxxx>
- Date: Fri, 24 Aug 2007 13:42:37 -0700
WP <mindcooler@xxxxxxxxx> writes:
I saw a discussion on a forum where two people were arguing if the
following program causes undefined behaviour (or at least undefined
output for a given program name and argument) or not (ignore the
failure to check argc, assume at least one argument is passed to the
program):
#include <stdio.h>
int
main(int argc, char ** argv)
{
printf("%s got %s\n", *argv++, *argv);
return 0;
}
I think I read that the order of evaluation of the arguments is not
specified so you could get the output:
thearg got progname
if you launched with
$ progname thearg
I'd like to hear what you gurus say (alot of people hanging on forums
do not seem to realise that this is the place to go for expert advice
btw).
Yes, the order of evaluation of arguments is not specified, so at the
very least it could print either "thearg got progname" or "progname
got thearg'. There are programs whose behavior can vary depending on
the order of argument evaluation without invoking undefined behavior.
Consider this rather contrived program:
#include <stdio.h>
int main(void)
{
printf("puts returns %d and %d\n",
printf("first\n"),
printf("second\n"));
return 0;
}
Its output can be either
second
first
puts returns 6 and 7
or
first
second
puts returns 6 and 7
but it can't legally do anything else (barring an I/O error).
But the printf call in your example:
printf("%s got %s\n", *argv++, *argv);
invokes undefined behavior because it violates C99 6.5p2:
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 store.
The evaluations of all three arguments occur between two consecutive
sequence points. The value of argv is not modified more than once, so
it doesn't violate the first sentence, but it's read to determine the
value to be stored in argv *and* to determine the value of the third
argument, which violates the second sentence.
You weren't asking how to write it correctly, but I'll answer that
anyway:
printf("%s got %s\n", argv[0], argv[1]);
argv++;
Or, if you insist on having side effects within your arguments:
printf("%s got", *argv++);
printf(" %s\n", *argv);
--
Keith Thompson (The_Other_Keith) kst-u@xxxxxxx <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
.
- Follow-Ups:
- Re: Does this program exhibit undefined behaviour or output?
- From: CBFalconer
- Re: Does this program exhibit undefined behaviour or output?
- References:
- Prev by Date: Re: Porting C software
- Next by Date: Re: C database :: compared to a relational database engine?
- Previous by thread: Does this program exhibit undefined behaviour or output?
- Next by thread: Re: Does this program exhibit undefined behaviour or output?
- Index(es):
Relevant Pages
|