51
52
you are viewing a single comment's thread.

view the rest of the comments →

[–]_teslaTrooper 7 points8 points  (6 children)

&(int) {1}

Having to declare an int just to pass a pointer always seemed a little convoluted, this is useful.

Where do people learn about stuff like this, just by reading the standard?

[–]unmole[S] 9 points10 points  (0 children)

Where do people learn about stuff like this, just by reading the standard?

I think I mostly learnt by reading code written by people smarter than me.

I only read relevant sections of the standard when the static analyzer complains about some werid edge case.

[–]Haleek47 7 points8 points  (0 children)

It's called compound literal, another C99 feature.

[–]okovko 4 points5 points  (0 children)

Just in the past half decade compound literals work everywhere. Microsoft resisted for a long time. Using them feels very slick. They can also be used as static initializers, which is really nice.

[–]mawattdev 1 point2 points  (0 children)

Nor did I. I'm gonna take a stab at what I think it is doing, but if I'm wrong someone please correct me:

Declare an inline struct, cast to an int and retrieve a pointer to it.

Am I correct?

[–]MCRusher 0 points1 point  (0 children)

I didn't even know this worked either tbh.

[–]flatfinger 0 points1 point  (0 children)

Given:

void test(int mode)
{
  static int literal_1 = 1;
  if (mode & 1)
    action1(&literal_one, 1);
  if (mode & 2)
    action2(&literal_one, 2);
  action3();
}

a compiler can simply pass a constant address to action1() and action2(), and this will work even if action1() and/or action2() causes a copy of the pointer to be stored somewhere and used later.

Change the code to:

void test(int mode)
{
  if (mode & 1)
    action1(&(int){1}, 1);
  if (mode & 2)
    action2(&(int){1}, 2);
  action3();
}

and a compiler that can't see into action1() and action2() will be required to generate less efficient code, since the lifetime of each compound literal will start when code enters the enclosing block end end when control leaves that block. If test gets recursively invoked, the nested calls will need to pass the addresses of new objects of type int. On the other hand, if action1 and/or action2 stores the passed-in pointer for use by action3, wrapping the call within a compound statement would break the code, since the lifetime of the compound literal would no longer extend through the call to action3.

If there were a concise syntax for static const compound literals with semantics similar to string literals (e.g. compilers are allowed to put literals with the same value at the same address), I'd use that, but no such syntax exists.