In C, is it ever OK to increment an uninitialized int?

According to this SO answer , incrementing an uninitialized int in C results in undefined behavior. But what if I don't care about the original value at all; For example, what if I just want to increment id? Is this a dangerous or bad practice for any reason?

+6
source share
3 answers

When most people read "this leads to undefined behavior", they initially interpret it as "the value of your variable of interest is indefinite."

This is not true.

Text literally means what it means: the behavior of the program itself is undefined.
If they would like to tell you that the meaning will be indefinite, then they will say that the meaning will be indefinite. But they did not. These are different sentences with different meanings.

When the behavior is undefined, it means that the program is pointless - for example, this variable can no longer exist even at the point at which you infer its value. The program may not even execute the code that you think so. It can just jump somewhere else, it can suddenly delete a file on your disk, it can do anything. The question of the value of the variable is completely absent.

As an example, it is used as bad , because although you can expect it to be equivalent to i = 0 , it will also lead to undefined behavior:

 int i; i -= i; 

ie, undefined behavior has nothing to do with the value of any particular variable. It is about behavior (verb), not data (noun).

+7
source

When the value of an object with automatic storage duration is reached, and the object is not initialized, the behavior is undefined. This is explicitly and formally stated in N1570 . 6.3.2.1 paragraph 2 (this is the last public draft of ISO C).

"Undefined behavior" means not only that you can get an arbitrary value. This means "behavior when using an intolerable or erroneous software construct or erroneous data for which this International Standard does not impose any requirements" ( N1570 3.4.3). The language standard literally says nothing about what access to such an asset value means. This is effectively pure gibberish. (The standard joke is that undefined behavior can cause demons to fly out of your nose. Of course, this is not possible in real life, but if so, you cannot complain that the compiler does not agree.)

But let it momentarily ignore the undefined behavior of accessing an uninitialized int . Maybe today you are lucky. Perhaps you know how your compiler will handle this case.

More precisely, let us assume some probable assumptions about how undefined behavior might look.

Let's pretend that:

 int i; i ++; 

Assume that the initial value (undefined) i is INT_MAX . Then the increment i causes an integer overflow of the sign, which is clearly clearly an undefined behavior ( N1570 6.5 clause 5). Even if the initial value is less than INT_MAX , incrementing it enough time will lead to overflow - and since you do not know what the initial value is, you do not know how many times you can "safely" increase it.

The most likely consequence is that the optimizing compiler will transform the code in a way that depends on the assumption that its behavior is defined. Here is an example that does not contain an uninitialized variable:

 int i = INT_MAX; int j = i + 1; if (j > i) { /* ... */ } 

If an add-on obeys the general semantics of the second add-on (not guaranteed by the C standard, but usually implemented in hardware), then j will be equal to INT_MIN , and (j > i) will be false. Logically, (j > i) must be false, because the value of int can exceed INT_MAX . But since j was set to i + 1 , then (j > i) should be true (for any program that defined the behavior).

Regardless of your expectations regarding the behavior of this code, the optimization compiler may legally violate them. If you are lucky, he may warn you before breaking your code, but this is not required.

You will spend much less time adding = 0 to ad i than we have discussed what will happen if you do not. (But even then you may run into problems if you increase i enough time to cause an overflow.)

+8
source

While "Undefined Behavior" is likely to be the value undefined in a variable, in no case should you write code that would make this assumption.

Some of the other posters make the behavior undefined, providing an extreme example of deleting your home directory. We all know that the example is extreme, but the point they make is not extreme.

Realistic future “Undefined Behavior” may be a segmentation error caused by improved memory error checking.

A memory error check performed by debugging tools such as "Clear" may detect such errors. It’s not quite right to think that these types of tools can evolve to have sufficiently low overheads that they will use in production code to trap such “Undefined behavior”.

That is, for some future implementations, "Undefined Behavior" will be a segmentation error.

+2
source

Source: https://habr.com/ru/post/981852/


All Articles