C are label addresses across function calls the same

when i store the address of a label with GCCs labels as values extension, are they the same across differently deep calls?

void *label = NULL;

int test() {
  if (label == NULL) {
    label = &&label_l;
  } else {
    goto *label;
  }
  
  return(test() + 1);
  
  label_l:
  return(0);
}

Will this work, even if the label was set in a different stack frame?

Upvotes: 2

Views: 131

Answers (1)

KamilCuk
KamilCuk

Reputation: 140990

are they the same across differently deep calls?

Generally, yes. From the documentation:

The &&foo expressions for the same label might have different values if the containing function is inlined or cloned. If a program relies on them being always the same, __attribute__((__noinline__,__noclone__)) should be used to prevent inlining and cloning. If &&foo is used in a static variable initializer, inlining and cloning is forbidden.

In your program it is not used in a static variable initializer, so it is possible that your function gets inlined or duplicated and the label will jump to different function - make sure it does not happen. (But even if you would do static void *label = &&label_l I would still add __attribute__((__noinline__,__noclone__)) to protect against later refactoring).

One real life example: protothreads may use labels as values to store the case statement to jump to.

Overall, do not use labels as values. If you intent to use it, prefer to only use it for automatic local variables. The code you presented looks like an invitation for unmaintainable spaghetti code.

even if the label was set in a different stack frame?

Yes, stack frame does not matter. We are living on (ok, "modified") Hardvard architecture, so what is in memory is separate and code location does not change.

Upvotes: 4

Related Questions