3

Im trying to get my head around declaration and definition of variables in C. My learning material from school says that global uninitialised variables are assigned 0 whereas uninitialised local variables are left unassigned and have a value that was present in that memory address.

However, I tried a following very simple program:

#include <stdio.h>

void something(){

    int third;
    int fourth;

    printf("third: %d\n", third);
    printf("fourth: %d\n", fourth);
}

int main(){
    int first;
    int second;

    printf("first: %d\n",first);
    printf("second: %d\n",second);
    something();
    return 0;
}

Output is following:

first: 382501330
second: 32766
third: 0
fourth: 0

Second run:

first: 235426258
second: 32766
third: 0
fourth: 0

Observations:

  • Variable 'first' seems to be assigned a random number every time as expected

  • Variable 'second' is assigned the same number (32766) every time, why?

  • Why variables 'third' and 'fourth' are assigned to zeros as they are local, not global variables?

1
  • 0 and 235426258 are just as random - there is only one of each among the possible bit patterns. Commented Jun 30, 2018 at 20:23

1 Answer 1

2

You're accessing uninitialized locals that could have been declared register. That's undefined behavior. Your program no longer makes sense.

If you fix it up by sprinkling in some & operators (so that the locals no longer can have been declared register)

#include <stdio.h>

void something(){

    int third;
    int fourth;

    printf("third: %d\n", *&third);
    printf("fourth: %d\n", *&fourth);
}

int main(){
    int first;
    int second;

    printf("first: %d\n", *&first);
    printf("second: %d\n", *&second);
    something();
    return 0;
}

then as far as C is concerned the values will be unspecified. What you'll get depends on your environemnt and what the main-calling libc-routine left in the stack before it made the call to main.

Sign up to request clarification or add additional context in comments.

2 Comments

While I personally agree with your interpretation, compiler authors either have a different one or cannot help writing compilers that have bugs when it comes to treating uninitialized memory as causing unspecified behavior instead of undefined. I wrote this blog post years ago: blog.frama-c.com/index.php?post/2013/03/13/… . The examples in the blog post are no longer compiled to show indeterminate-access-as-UB, but it still only takes a few minutes of fooling around to write an example for a recent compiler: godbolt.org/g/NYjb2e
Thanks for the comment with the links. Worth more than my answer. (Though for a newbie, my answer perhaps could be sufficient. ) Trusting compilers on handling the corner cases of the standard is definitely not something I'd advise after too getting burned a couple of times... Well, at least gcc seems to be doing it right.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.