Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In C, is it ever O.K. 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 at all about the initial value; for example, what if I just want an incrementing id? Is this dangerous or bad practice for any reason?

like image 825
jds Avatar asked Feb 02 '15 04:02

jds


People also ask

What is the value of uninitialized int in C?

0 if static or global, indeterminate if storage class is auto. C has always been very specific about the initial values of objects. If global or static , they will be zeroed.

What happens when you don't initialize a variable in C?

Unlike some programming languages, C/C++ does not initialize most variables to a given value (such as zero) automatically. Thus when a variable is assigned a memory location by the compiler, the default value of that variable is whatever (garbage) value happens to already be in that memory location!

Are uninitialized variables bad?

"Uninitialized variables contain some value" is a incorrect statement which unfortunately is teached. A program who access an uninitialized variable has Undefined Behavior, which means it can have any behavior. @bolov Perhaps we're on the wrong page.

Are uninitialized variables null in C?

(However, default initialization to 0 is a right practice for pointers and arrays of pointers, since it makes them invalid before they are actually initialized to their correct value.) In C, variables with static storage duration that are not initialized explicitly are initialized to zero (or null, for pointers).

How to increment and decrement in C++?

C++ Server Side Programming Programming. The increment operator ++ adds 1 to its operand, and the decrement operator -- subtracts 1 from its operand. So, x = x+1; is the same as x++; And similarly, x = x-1; is the same as x--; Both the increment and decrement operators can either precede (prefix) or follow (postfix) the operand.

How to increment a variable from 0 to 1 in C++?

Step 1 : In above program, value of “i” is incremented from 0 to 1 using pre-increment operator. Step 2 : This incremented value “1” is compared with 5 in while expression. Step 3 : Then, this incremented value “1” is assigned to the variable “i”.

What is the pre-increment and post-increment concept in C/C++?

Pre-increment and Post-increment concept in C/C++? The increment operator ++ adds 1 to its operand, and the decrement operator -- subtracts 1 from its operand. So, Both the increment and decrement operators can either precede (prefix) or follow (postfix) the operand.

How to use the prefix increment/decrement operator?

Let's start with the first one. The prefix increment/decrement operator immediately increases or decreases the current value of the variable. This value is then used in the expression. Let's take an example: Here first, the current value of x is incremented by 1.


2 Answers

If the value of an object with automatic storage duration is accessed, and the object is uninitialized, the behavior is undefined. This is explicitly and formally stated in N1570 6.3.2.1 paragraph 2 (that's the latest public draft of the ISO C standard).

"Undefined behavior" doesn't just mean that you might get any arbitrary value. It means "behavior, upon use of a nonportable or erroneous program construct or of erroneous data, for which this International Standard imposes no requirements" (N1570 3.4.3). The language standard says literally nothing about what accessing such an object's value means. It's effectively pure gibberish. (The standard joke is that undefined behavior can cause demons to fly out of your nose. Of course in real life it can't -- but if it did you couldn't complain that the compiler is non-conforming.)

But let's ignore for a moment the undefined behavior of accessing an uninitialized int. Maybe you're feeling lucky today. Maybe you know how your compiler will handle this case.

More precisely, let's make some plausible assumptions about how that undefined behavior can manifest.

Suppose we have:

int i;
i ++;

Suppose the (undefined) initial value of i happens to be INT_MAX. Then incrementing i causes a signed integer overflow, which again is explicitly undefined behavior (N1570 6.5 paragraph 5). Even if the initial value is less than INT_MAX, incrementing it enough times will cause an overflow -- and since you don't know what the initial value is, you don't know how many times you can "safely" increment it.

The most likely bad consequence is that an optimizing compiler will transform the code in ways that depend on the assumption that its behavior is defined. Here's an example not involving an uninitialized variable:

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

If addition obeys the common wraparound 2's-complement semantics (which are not guaranteed by the C standard, but are commonly what's implemented in hardware), then j will be equal to INT_MIN, and (j > i) will be false. Logically, (j > i) must be false, because no int value can exceed INT_MAX. But since j was set to i + 1, then (j > i) must be true (for any program that has defined behavior).

Whatever your expectations might be for the behavior of this code, an optimizing compiler may legally violate them. If you're lucky, it might warn you before breaking your code, but it's not required to.

You'll spend far less time adding an = 0 to the declaration of i than we've spent discussing what happens if you don't. (But even then, you might run into problems if you increment i enough times to cause an overflow.)

like image 75
Keith Thompson Avatar answered Nov 15 '22 02:11

Keith Thompson


When most people read "this results in undefined behavior" they initially interpret it as "the value of your-variable-of-interest is indeterminate".

This is wrong.

The text means literally what it means: the behavior of the program itself is undefined.
If they wanted to tell you that a value would be indeterminate, then they would say the value would be indeterminate. But they didn't. These are different sentences with different meanings.

When the behavior is undefined, it means the program is meaningless -- for example, the variable may no longer even exist at the point at which you make an inference about its value.
The program may not even be executing the code you think it is. It might just jump somewhere else, it might suddenly delete a file on your disk, it could do anything. Questioning the value of the variable is completely missing the point.

This is just as bad as your example, because while you might expect it to be equivalent to i = 0, it also results in undefined behavior:

int i;
i -= i;

i.e., undefined behavior has nothing to do with the value of any particular variable. It's about behavior (verb), not data (noun).

like image 23
user541686 Avatar answered Nov 15 '22 00:11

user541686