0
#include<stdio.h>

void m(int *p){
    int i=0;
    for(int i=0;i<5;i++)
        printf("%d",p[i]);
}

int main(){
    int a[5]={4,5,6};
    m(a);
}

I expect the output will be 4 5 6 junkValue junkValue ,but the actual output is 4 5 6 0 0

Support Ukraine
  • 42,271
  • 4
  • 38
  • 63
  • 4
    When you supply too few initialisers like this the remaining elements are initialised to zero, so this is expected behaviour. – Paul R Apr 27 '19 at 07:38
  • 4
    @danglingpointer: How is this UB? `a` _does_ have 5 entries and the entries `a[3]` and `a[4]` are implicitly initialised to `0` by standard initialisation rules. – M Oehm Apr 27 '19 at 07:38
  • 2
    OT: `int i=0;` can be deleted – Support Ukraine Apr 27 '19 at 07:42
  • 3
    While in this case it's well-defined behavior and does what's specified, you should know that even `0` could be a "garbage" value. Depending on development environment and build-mode (debug versus release for example) the environment could fill all otherwise uninitialized data with zero. And sometimes the indeterminate values could happen to be zero as well. So even if it it behaved as you expected, those junk values could very well be zero. – Some programmer dude Apr 27 '19 at 07:47

3 Answers3

6

In section "6.7.9 Initialization" of the standard it says:

If there are fewer initializers in a brace-enclosed list than there are elements or members of an aggregate, or fewer characters in a string literal used to initialize an array of known size than there are elements in the array, the remainder of the aggregate shall be initialized implicitly the same as objects that have static storage duration

As int is zero initialized when used as static objects, the code:

int a[5]={4,5,6};

is really the same as

int a[5]={4,5,6,0,0};

So there will be no "junk values" printed. It will (and must) print the two zeros.

Support Ukraine
  • 42,271
  • 4
  • 38
  • 63
1

In C there is no partial initialization.

An object either is not initialized or is fully 100% initialized (to 0 of the right kind in the absence of any other initializer)

int a[5] = {4, 5, 6}; // a[0] = 4, ..., a[3] = a[4] = 0;
int b[5]; // uninitialized
b[0] = 4;
b[1] = 5;
b[2] = 6;
m(b); // b[3] and b[4] have not been initialized/assigned
      // accessing them is UB
pmg
  • 106,608
  • 13
  • 126
  • 198
  • IIRC, in C reading indeterminate values is only UB if the value happen to be a trap-value, which for integers will never be the case. – Some programmer dude Apr 27 '19 at 07:49
  • 1
    @Someprogrammerdude see [C11 6.2.6.2p5](http://port70.net/~nsz/c/c11/n1570.html#6.2.6.2): "... A valid (non-trap) object representation of a signed integer type ..." – pmg Apr 27 '19 at 07:53
1

int a[5]={4,5,6}; is a partially initialized array. Uninitialized array elements a[3], a[4] are initialized to zero. So this is expected behavior.