Reputation: 2373
What tasks, features, executions vary with compiler? I know this code is compiler-dependent-
#include <stdio.h>
#define PRODUCT(x)(x*x)
int main()
{
int i=3,j,k;
j=PRODUCT(i++);
k=PRODUCT(++i);
printf("\n%d %d",j,k);
}
Following gives garbage in some, while fixed values in others-
#include <stdio.h>
int main()
{
int i=5,j=10;
printf("%d,%d");
}
So order of execution vary with compilers. Are such ambiguous programs eligible to be asked in exams?
Upvotes: 1
Views: 6022
Reputation: 180145
As you've asked about C++ as well, here's the C++11 answer (which is different from C++98 and C99):
Undefined behavior isn't really compiler dependent. Since anything can happen, and a compiler isn't even required to be consistent with itself, the resulting behavior cannot be said to depend on the compiler.
Upvotes: 3
Reputation: 231373
If you want the full list, you'll need to look to the standard document. In the C standard there are two types of 'compiler-dependent' issues defined:
-1 >> 1
may vary between compilers, but the compiler has to be consistent about it.You also need to watch out for constraint violations. Often the standard specifies things like "[main
] shall be defined with a return type of int
[...]" (§5.1.2.2.1/1). This is equivalent to, "If main
is declared with a return type other than int
, the program's behavior is undefined." (see §4.2, where the standard explicitly endorses this interpretation)
You should not be asked these questions on an exam; if you are, you should simply state that the behavior of the program is undefined (or implementation-defined). Note that some implementation-defined behavior has limits - eg, the value of sizeof(int)
is implementation defined, but you know that sizeof(int) >= sizeof(short) && sizeof(int) <= sizeof(long)
- so just having any implementation-defined behavior doesn't mean you can't say anything about what the program does.
Upvotes: 12
Reputation: 62106
I recommend that you get copies of the C and C++ standards (they aren't expensive to buy or you might use one of the publicly available drafts) and read them.
While reading, note all the things that are marked as unspecified behavior
, undefined behavior
, implementation-defined behavior
, common extensions
and so on.
There's this section, Annex J "Portability Issues", in the C standard that's entirely devoted to this kind of things. Similar things (including the differences between C and C++) are listed in the C++ standard as well.
The standards will give you the ultimate answers to questions of this type. Also, watch out for non-compliant (to the standard) behavior of your compiler, check its documentation too.
Upvotes: 0
Reputation: 125007
Are such ambiguous programs eligible to be asked in exams?
Naturally, that depends on the person giving the exam and the exam topic. I wouldn't be surprised to see a program containing undefined behavior on an exam about the C programming language, but I'd be very surprised if the "correct" answer were anything other than "the behavior of that program is undefined."
Upvotes: 3
Reputation: 4523
Well, too many, I think one way to find them is check the C99 standard, then search for keyword undefined
and implementation-defined
.
Upvotes: 0
Reputation: 361692
Both program invoke undefined behaviour (UB).
The first program invokes UB, because the macro expands to i++ * i++
and ++i*++i
respectively, and each expression invokes UB, as they both attempt to modify the object i
more than once without any intervening sequenct point.
Second program invokes UB, because the format string doesn't match the arguments.
Upvotes: 0
Reputation: 3433
That isn't a compiler ambiguity - your program is ill-formed.
Incrementing the same variable twice in an expression produces undefined behaviour.
If that sort of question is asked in an exam, you are well within your rights to state that and not answer the question.
To answer your questions, the major compilers (GCC, MSVC) don't differ in any really significant ways that I know of, at least until you get into the stratosphere of meta-programming techniques. They both seem to optimise about the same way and have basically the same support for C++11 features.
Upvotes: 3
Reputation: 112404
The first one is actually compiler dependent because what it resolves to is (i++ * i++)
. The compiler is free to order those operations to its own needs because the expression doesn't have "sequence points".
Wikipedia has a good article on sequence points.
The first example is indeed the sort of thing that happens in quizzes, and the correct answer is "the result is indeterminate."
The second one is simply incorrect; you're lucky it didn't give you a segmentation fault or the like. Observe the printf
: it's attempting to pull two values of the stack that haven't been pushed. The value you see printed is whatever happens to be on the stack, and if you had another function call following, it would very likely fail at that point.
Upvotes: 3