문제

I'm reading this tutorial about debugging. I pasted the factorial code in my .c archive:

#include <stdio.h>

int main()
{
    int i, num, j;
    printf ("Enter the number: ");
    scanf ("%d", &num );

    for (i=1; i<num; i++)
        j=j*i;    

    printf("The factorial of %d is %d\n",num,j);
}

When I run the executable, it always print 0, however, the author of the tutorial says that it return numbers garbage value. I've googled about this and I've read that this is right, except for static variables. So it should return a garbage number instead of 0.

I thought that this might be due to a different version of C, but the guide is from 2010.

Why do I always see 0, instead of a garbage value?

도움이 되었습니까?

해결책

Both the C99 draft standard and the C11 draft standard say the value of an uninitialized automatic variable is indeterminate, from the draft c99 standard section 6.2.4 Storage durations of objects paragraph 5 says (emphasis mine):

For such an object that does not have a variable length array type, its lifetime extends from entry into the block with which it is associated until execution of that block ends in any way. (Entering an enclosed block or calling a function suspends, but does not end, execution of the current block.) If the block is entered recursively, a new instance of the object is created each time. The initial value of the object is indeterminate. If an initialization is specified for the object, it is performed each time the declaration is reached in the execution of the block; otherwise, the value becomes indeterminate each time the declaration is reached.

the draft standard defines indeterminate as:

either an unspecified value or a trap representation

and an unspecified value is defined as:

valid value of the relevant type where this International Standard imposes no requirements on which value is chosen in any instance

so the value can be anything. It can vary with the compiler, optimization settings and it can even vary from run to run but it can not be relied and thus any program that uses a indeterminate value is invoking undefined behavior.

The standard says this is undefined in one of the examples in section 6.5.2.5 Compound literals paragraph 17 which says:

Note that if an iteration statement were used instead of an explicit goto and a labeled statement, the lifetime of the unnamed object would be the body of the loop only, and on entry next time around p would have an indeterminate value, which would result in undefined behavior.

this is also covered in Annex J.2 Undefined behavior:

The value of an object with automatic storage duration is used while it is indeterminate (6.2.4, 6.7.8, 6.8).

In some very specific cases you can make some predictions about such behavior, the presentation Deep C goes into some of them. These types of examination should only be used as a tool to further understand how systems work and should never even come close to a production system.

다른 팁

You need to initialize j to 1. If j happens to be zero, the answer will always be zero (one type of garbage). If j happens to non-zero, you'll get different garbage. Using uninitialized variables is undefined behaviour; 'undefined' does not exclude always being zero in the tests you've done so far.

Some systems have their memory set to 0 (Mac OS for example) so your variable will often contain 0 when you initialise it but it's a bad practice that will lead to unstable results.

You can't say what should happen in this case because the language specification doesn't say what should happen. In fact it says that the values of uninitialised non-static variables are indeterminate.

That means they can be any value. They can be different values on different runs of your program, or when your code is compiled on a different compiler, or when compiled on the same compiler with different optimisation settings. Or on different days of the week, national holidays or after 6pm.

An uninitialised variable can even hold what's called a trap representation, which is a value which is not valid for that type. If you access such a value then you're into the scary world of undefined behaviour where literally anything can happen.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top