Why is int i used; undefined, but using the rand () value is not?

If I don't initialize i

, I don't know its value, but I also can't predict the value rand()

.

But on the other hand, I know that the uninitialised value i

is between INT_MIN

and INT_MAX

, and I also know that the value rand()

is between 0

and RAND_MAX

.

Why is the value of the uninitialized behavior i

undefined, but using the value is rand()

not?

+3


source to share


6 answers


The value of the uninitialized variable is undefined . The return value rand()

is clearly defined as the next number in a pseudo-random sequence for a given seed .

You can rely on rand()

returning a pseudo-random number. You cannot rely on any characteristic of an uninitialized value int i

.



I have looked at the C99 standard (ISO / IEC 9899: 1999), which is the only standard document I have, but I seriously doubt this has changed. Chapter 6.2.6 "Type Representations" states that integers can be stored in memory with padding bits whose meaning is undefined, but can include parity bits that will be set after initialization and any arithmetic operation on an integer. Some representations ( e.g. parity mismatch) can be traps whose behavior is undefined (but may well terminate your program).

So no, you can't even rely on uninitialized int i

like INT_MIN

<= i

<= INT_MAX

.

+7


source


The standard says that reading from an uninitialized variable is undefined behavior, and it is. You cannot say that it is between INT_MIN

and INT_MAX

. In fact, I can't really think of this variable as any value, so you couldn't even test this hypothesis * .

rand()

, on the other hand, is designed to generate a random number within a range. If the read from the result rand()

was undefined, it would not be part of any library, because it could not be used.




* Usually "undefined behavior" provides opportunities for optimization. The optimizer can do whatever it wants with an uninitialized variable, under the assumption that it is unreadable.

+5


source


The value is rand

determined to be (pseudo) random. The value of an uninitialized variable is not defined by anything. Therein lies the difference, whether something is definite something significant (while it rand()

also makes sense - it gives (pseudo) random numbers) or undefined.

+2


source


The short answer, as others have said, is because the standard says it.

The act of accessing the value of a variable (described in the standard as performing an lvalue to rvalue conversion) that is not initialized gives undefined behavior.

rand()

is specified as a value from 0 to RAND_MAX

, where RAND_MAX

(a macro declared in <cstdlib>

for C ++ and <stdlib.h>

for C) is specified as having the value that is in the smallest 32767

.

+2


source


rand

uses an algorithm to generate your number. Thus, it is rand

not undefined, and if srand

you choose 42 when using to run random generation, you will always get the same value every time you start the application, try running this example, you will see:

#include <stdio.h>
#include <stdlib.h>

int main()
{
  srand(42);

  printf("%d\n", rand());
  return 0;
}

      

see also: https://en.wikipedia.org/wiki/List_of_random_number_generators

+1


source


Consider the variable x

in the following code:

uint32_t blah(uint32_t q, uint32_t r)
{
  uint16_t x;
  if (q)
    x=foo(q); // Assume return type of foo() is uint16_t
  if (r)
    x=bar(r); // Assume return type of bar() is uint16_t
  return x;
}

      

Since the code never assigns a x

value outside the range 0-65535, the compiler for a 32-bit processor can legitimately allocate a 32-bit register for it. Indeed, since the value is q

never used after it was first written x

, the compiler could use the same storage register x

that it used for storage q

. Ensuring that the function always returns 0-65535 would require additional instructions compared to simply being able to return everything that went into the register allocated for x

.

Note that from the point of view of the authors of the Standard, if the Standard does not require the compiler to x

keep the value from 0-65535, it may also be silent about what might happen if the code tries to use x

. Implementations that wish to provide some sort of behavior assurance in such cases are free to do so, but the standard makes no requirements.

+1


source







All Articles