2

What does the code below print when running the function print_test()?

struct test {
  int a, b, c;
};

void print_test(void) {
  struct test t = {1};
  printf("%d/%d/%d", t.a, t.b, t.c);
}

Solution 1\0\0

Why are b and c initialized to zero even though I did not do it? Are there any default values for the struct? However, the struct is not global and the member is not static. Why are they automatically zero-initialized? And if the data type were not int another data type to which value will be initialized?

  • 3
    Please note that many of us old-timers dislike the term "C/C++". There's no such language as "C/C++", only the two very different languages C and C++. While there's some common syntax, and *sometimes* similar semantics, they are still different and sometimes things that might seem the same are actually different. – Some programmer dude Sep 01 '20 at 08:55
  • As for your problem, [this structure/union initialization reference](https://en.cppreference.com/w/c/language/struct_initialization) might be helpful. – Some programmer dude Sep 01 '20 at 08:56
  • ok i will edit it. thanks a lot for your note – Abdelrahman Elayashy Sep 01 '20 at 08:56
  • Do discuss your question in detail you should better provide a [mre]. – Yunnosch Sep 01 '20 at 08:57
  • 1
    Please describe what you do expect instead of 0. That is not obvious from your question. – Yunnosch Sep 01 '20 at 08:58
  • Although @tenfour's answer is correct, if you showed a situation in which the members were not initialized, you could _still_ have seen zeroes. Zero is a possible value for an uninitialized integer, and a program with UB could produce the same output. Hence the question about what you expected to see instead. – Useless Sep 01 '20 at 09:03
  • ok thanks a lot for all you guys. – Abdelrahman Elayashy Sep 01 '20 at 09:06
  • In C, `struct test t = {1};` the remaining member variables will be zero-initialized. In C++, `test t = {};` all member variables will be zero-initialized, since in this case `test` does not have a constructor that takes an initialization list. Last time I checked, C does not support the syntax that C++ does, and requires at least one value in the initializer. Why? Because that is what their respective standards say must happen. – Eljay Sep 01 '20 at 11:49
  • In the end, who cares? If you care what the initial values of a data structure are, set the darned things and be done with. And if you don't care, why worry? – Kevin Boone Sep 01 '20 at 12:34
  • @KevinBoone who's worrying? – tenfour Sep 01 '20 at 12:52
  • @tenfour -- well, somebody was concerned enough to ask the question. It's the kind of question that you get in multiple-choice examinations. – Kevin Boone Sep 01 '20 at 12:56
  • @KevinBoone let's not conflate curiosity with "worry". And let's also not discourage curiosity. If you just don't find the question interesting enough, feel free to pass it by. – tenfour Sep 01 '20 at 13:26
  • @tenfour -- it's OK to be curious, of course. It's just not OK to ask questions like this in exams, and this smells like an exam question. I might be mistaken, however. I've been known to be wrong before. – Kevin Boone Sep 01 '20 at 14:56

2 Answers2

3

If you don't specify enough initializers for all members of a struct, you'll face Zero initialization, which will initialize remaining members to 0. I think by today's standards this seems a bit odd, especially because C++'s initialization syntax has evolved and matured a lot over the years. But this behavior remains for backwards-compatibility.

tenfour
  • 36,141
  • 15
  • 83
  • 142
  • Just curious, if you consider this behaviour to be odd, what would you expect to be more intuitive behaviour? – th33lf Sep 01 '20 at 09:38
  • @th33lf just my opinion of course but I'd expect a warning/error, and leave remaining fields uninitialized. `0` in this context feels like an arbitrary magic number and if that's what you want you should specify it. I would feel the same way if you fail to provide enough arguments to a function call. It would be unintuitive for the compiler to silently fill in remaining arguments with the number `0`. – tenfour Sep 01 '20 at 09:43
1

I think we need to know two points at this stage:

  1. There is nothing different between regular variables and structs, if they are at local scope i.e automatic storage duration. They will contain garbage values. Using those values could invoke undefined behaviour.

The only thing that makes structs different is that if you initialise at least one of the members, the rest of the members will get set to zero i.e. initialised as if they had static storage duration. But that's not the case when none of the members are initialised.

  1. It depends on your declaration. If your declaration is outside any function or with the static keyword (more precisely, has static storage duration), the initial value of x is a null pointer (which may be written either as 0 or as NULL).

If it's inside a function i.e. it has automatic storage duration, its initial value is random (garbage).

consider the following code:

#include<stdio.h>
#include<unistd.h>

struct point {
    int x, y;
    char a;
    double d;
};    
typedef struct point Point;

void main(){ 
    Point p1;
    printf("\nP1.x: %d\n", p1.x);
    printf("\nP1.y: %d\n", p1.y);
    printf("\nP1.a: %d\n", p1.a);
    printf("\nP1.d: %lf\n", p1.d);

    Point p2 = {1};
    printf("\nP2.x: %d\n", p2.x);
    printf("\nP2.y: %d\n", p2.y);
    printf("\nP2.a: %d\n", p2.a);
    printf("\nP2.d: %lf\n", p2.d);
}

The output is :

P1.x: 0

P1.y: 66900

P1.a: 140

P1.d: 0.000000

P2.x: 1

P2.y: 0

P2.a: 0

P2.d: 0.000000

A Good read: C and C++ : Partial initialization of automatic structure

Muhammad
  • 381
  • 3
  • 10