开发者

On C/C++, basically what things are compiler-dependent?

开发者 https://www.devze.com 2023-04-12 07:16 出处:网络
What tasks, features, executions vary with compiler? I know this code is comp开发者_JS百科iler-dependent-

What tasks, features, executions vary with compiler? I know this code is comp开发者_JS百科iler-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?


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:

  • Implementation-defined behavior: The behavior may vary from compiler to compiler, but the compiler must provide some sort of consistent behavior, and must document this behavior. An example, straight from the standard: "An example of implementation-defined behavior is the propagation of the high-order bit when a signed integer is shifted right.". In other words, the result of -1 >> 1 may vary between compilers, but the compiler has to be consistent about it.
  • Undefined behavior: All bets are off. The moment you hit undefined behavior, anything - and I do mean anything can happen. Your code is a good example of this - you modify a single variable twice without an intervening sequence point (in violation of ISO/IEC 9899:1999 (E) §6.5's constraint). And in the second one, you are missing parameters (undefined behavior per §7.19.6.1/2). According to a strict reading of the standard, it is perfectly justified for the compiler to summon demons through your nose in this case.

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.


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.


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.


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."


As you've asked about C++ as well, here's the C++11 answer (which is different from C++98 and C99):

  • conditionally-supported constructs (1.3.5)
  • implementation-defined behavior (1.3.10), obviously
  • implementation limits (1.3.11), such as the maximum number of function arguments.
  • available locales and their behavior (1.3.12, 1.4)
  • unspecified behavior (1.3.25)
  • diagnostic messages produced (1.4), not all errors require a diagnostic.
  • implementation details of the standard library (1.4) - this covers a lot of possible variation.
  • extensions (1.4)
  • character sets used (2.3)

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.


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.


Well, too many, I think one way to find them is check the C99 standard, then search for keyword undefined and implementation-defined.


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.

0

精彩评论

暂无评论...
验证码 换一张
取 消