7

Context

Reading some kernel code.

Problem

I cannot get my head on what this line is meaning

*(void **) &(int[2]){0,PAGE_SIZE};

and more, what does this means

{0,PAGE_SIZE}

To me it doesn't look like a function with that comma.

What could be going on with this code ? I don't understand the indirections here.

Is it a function or a cast ? What does the bracket part means ? Seems so convoluted to me but definitely has a meaning.

Community
  • 1
  • 1
Larry
  • 1,735
  • 1
  • 18
  • 46
  • 3
    [Compound literals](https://gcc.gnu.org/onlinedocs/gcc-3.1/gcc/Compound-Literals.html). –  Sep 15 '14 at 19:48
  • 3
    :sigh: This is what happens when people try to get cute. Should probably just be `int[] const foo = {0, PAGE_SIZE}; *(void**)(&foo);` – Billy ONeal Sep 15 '14 at 19:50
  • @BillyONeal: Inside a macro, this would make sense (however GCC special block syntax would help here, since this is kernel code). – Alexandre C. Sep 15 '14 at 20:22

1 Answers1

7
(int[2]) { 0, PAGE_SIZE }

is an expression (called compound literal) whose value is an array of two ints. The address of this array is taken, casted to void **, and dereferenced.

The net result is a reinterpretation of the array contents as a pointer to void.

Note that you can take the address of a compound literal, as they are lvalues. See eg. this question.

Community
  • 1
  • 1
Alexandre C.
  • 55,948
  • 11
  • 128
  • 197
  • How can you take the address of an expression? I thought you could only do that to lvalues. – templatetypedef Sep 15 '14 at 19:51
  • Because when you talk about arrays,the address only is referenced by default!Your doubt would have been valid for primitives like int type variables,etc. @templatetypedef... – Am_I_Helpful Sep 15 '14 at 19:56
  • @shekharsuman I'm not sure I understand what you're saying. If you give the *name* of an array as an lvalue, then it implicitly decays to a pointer to the first element of the array. Here, though, since the array results from a cast, it doesn't seem like the same rules should apply. Or am I mistaken? – templatetypedef Sep 15 '14 at 19:59
  • @templatetypedef-*Exactly* for the first statement! Whereas,array is resulting from cast as well it is trivially array because of `{...}`! You just try to assign `{...}` to a non-pointer OR non-array variable,and you'll receive the error! – Am_I_Helpful Sep 15 '14 at 20:03
  • 1
    @templatetypedef I'm guessing that the compound literal syntax is what coerces it into a pointer to the first element. –  Sep 15 '14 at 20:03
  • @remyabel Even if that's the case, you can't apply the `&` operator to non-lvalues (or can you?) – templatetypedef Sep 15 '14 at 20:04
  • @templatetypedef-Why do you think that `&` can't be applied to non-lvalues? What about references? Haven't I understood your point properly! Also,the first point to add is that `compound literal` has a much bigger role to play! – Am_I_Helpful Sep 15 '14 at 20:06
  • @templatetypedef-Why don't you verify it by checking the very first example on this link--->`https://gcc.gnu.org/onlinedocs/gcc-3.1/gcc/Compound-Literals.html` – Am_I_Helpful Sep 15 '14 at 20:09
  • @templatetypedef: IIRC, compound literals *are* lvalues (ie. they are not casts but special constructs). – Alexandre C. Sep 15 '14 at 20:17
  • Got it - I didn't realize that compound literals are defined to be lvalues. Everything makes sense now! – templatetypedef Sep 15 '14 at 20:18
  • @templatetypedef: see http://stackoverflow.com/questions/24739998/array-as-compound-literal – Alexandre C. Sep 15 '14 at 20:19
  • Thanks Alexandre. My way to master c is still long I think :) – Larry Sep 15 '14 at 20:21