0
#include <stdio.h>
#include <stdarg.h>

int main()
{
    int x,y;

    y = sizeof(int[]){0,1,2,3,4} ;
    x = y / sizeof(1);

    printf("Number of arguments: %d", x);

    return 0;
}

This code gives the no. of variables present in the array. (See variable y) How this array is initialized? I think the array is initialized this way: int a[]={variables}. If there are more ways to initialize the array please mention.

Capybara
  • 1,313
  • 8
  • 12

3 Answers3

2

The code uses a compound literal to have an "inline" (anonymous) array.

Since the array is only used with sizeof, no actual runtime array is constructed or initialized, this is all done at compile-time by the compiler simply inspecting the code and figuring out its type.

A quick godbolting gives us:

push    rbp
mov     rbp, rsp
mov     DWORD PTR [rbp-20], edi
mov     QWORD PTR [rbp-32], rsi
mov     DWORD PTR [rbp-4], 20    # Load 'y' with 20 (size of 5 ints)
mov     eax, DWORD PTR [rbp-4]
cdqe
shr     rax, 2                   # Divide by four, giving 5.
mov     DWORD PTR [rbp-8], eax
mov     eax, DWORD PTR [rbp-8]
pop     rbp
ret

By the way: you're being inconsistent in your use of parentheses; they're not needed with sizeof unless the argument is a type name, so the second use could be just

x = y / sizeof 1;

These two are commonly combined, but that's not possible here since your array is anonymous, of course.

unwind
  • 391,730
  • 64
  • 469
  • 606
  • 4
    Parenthesis around `sizeof` (for expressions) is a matter of style. I always put them. – Basile Starynkevitch Aug 29 '17 at 10:37
  • my question is how array(int[ ]) is initialized with values(0,1,2,3,4) . i haven't seen this way of initialization. – KARAN SHARMA Aug 29 '17 at 10:41
  • @BasileStarynkevitch Sure. Some people use them with `return` too, but I like to shine a light on how the language works when possible, I have a feeling there's a lot of cargo-culting around these things which I find annoying. – unwind Aug 29 '17 at 10:42
  • @Basile Starynkevitch I do exactly the same. IMO the code is clearer. – 0___________ Aug 29 '17 at 10:48
  • 1
    @unwind it may be even more optimised as x,y have constant values and are never used as variables :) `.LC0: .string "Number of arguments: %d" main: sub rsp, 8 mov esi, 5 mov edi, OFFSET FLAT:.LC0 xor eax, eax call printf xor eax, eax add rsp, 8 ret` So the value `5` is used to call the `printf` – 0___________ Aug 29 '17 at 10:49
  • I don't know what's cargo-culting about it or how this enlightens on "how the language works". The C language's grammar allows both styles and the "better" is decidedly subjective here. – P.P Aug 29 '17 at 10:51
1

(int[]){0,1,2,3,4 is a compound literal (introduced in C99) constructing an array. This simply construct an array on the fly.

n1570-§6.5.2.5/p3:

A postfix expression that consists of a parenthesized type name followed by a brace-enclosed list of initializers is a compound literal. It provides an unnamed object whose value is given by the initializer list.99)

sizeof (int[]){0,1,2,3,4} gives the size of array (int[]){0,1,2,3,4} in bytes. sizeof (1) gives the size of an int and therefore y/ sizeof (1) gives the number of elements in the array.

haccks
  • 104,019
  • 25
  • 176
  • 264
1

In this statement

y=sizeof (int[]){0,1,2,3,4} ;

there are two things. The first one is there is used compound literal int[]){0,1,2,3,4} of the type int[5]. It is an unnamed integer array. There is used the compound literal that to get the number of elements from the number of initializers. Take into account that neither array is created because the sizeof operator does not evaluate the expression. It just determines its type.

In fact this statement is equivalent to

y = sizeof( int[5] );

Using the compound literal just allows the compiler itself to calculate the number of elements in the array instead of doing this by you yourself.

Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335