13

In Clang API, there is a GotoStmt and an IndirectGotoStmt. There is very little explanation on the difference between these two kinds of goto statments. I know what a goto label; statement is. But what is an indirect goto statement? I want to know what that is in the context of C/C++ code, not necessarily just Clang. What does it mean syntactically to have an indirect goto statement? Can you provide a code example?

Edit: The following question is interesting.

Can you make a computed goto in C++

Galaxy
  • 2,363
  • 2
  • 25
  • 59
  • 1
    You are asking about impletation details. Those are irrelevant as far as C++ is concerned. – Jesper Juhl May 26 '19 at 19:45
  • My wild guess is, that this is a goto statement to a location contained in a variable, it is a gcc extension and clang aims for compatibility with gcc. – user1095108 May 26 '19 at 19:46
  • Perhaps it is similar to a switch case statement? But Clang API already has a specific class for that [`SwitchCase `][3]. [3]: http://http://clang.llvm.org/doxygen/classclang_1_1SwitchCase.html – Galaxy May 26 '19 at 19:47
  • @Galaxy Please add how the linked question is interesting. Does it relate to your question at all? – S.S. Anne May 31 '19 at 11:25
  • 1
    @JL2210 That linked question is a related question. In that question we can also find information about GCC's address of a label extension, and how to use it. People reading my question would want to read that question too to learn more about this coding construct in detail. Linked questions tend to be related in some way. Here we see a clear relationship because both questions are about that same coding construct. – Galaxy May 31 '19 at 23:25
  • @Galaxy Thank you. Good to know. – S.S. Anne May 31 '19 at 23:34

1 Answers1

9

There is a GNU extension that allows taking an address of a label, storing it for later use, then goto that address at a later point. See https://gcc.gnu.org/onlinedocs/gcc/Labels-as-Values.html for details. Example:

    void *ptr;

    if(...)
        ptr = &&foo;
    else
        ptr = &&bar;

    /* ... */
    goto *ptr;

foo:
    /* ... */

bar:
    /* ... */

Clang supports that too, as it aims at being compatible with GCC.

The use of the above might be, for example, in implementing state machines.

Yakov Galka
  • 70,775
  • 16
  • 139
  • 220
  • What is the `&&` operator? Is that how you take the address of a label? It looks like taking the address of the address, which doesn't make sense. I've never encountered that syntax before. – Galaxy May 26 '19 at 19:54
  • @Galaxy: yes, it's a GNU extension for an address of a label. **It is not part of any of C or C++ standards.** – Yakov Galka May 26 '19 at 19:55
  • @Galaxy Everything is explained in the link – klutt May 26 '19 at 19:55
  • @ybungalobill So if GCC has this feature, and clang supports that too, can I compile code having this feature using `clang++ main.cpp`, and it will work? – Galaxy May 26 '19 at 20:01
  • @CareyGregory I actually think that for certain applications if could be useful to programmatically determine an address in the executable code region of the memory, and later have the instruction pointer jump to that region. Maybe it could be useful for systems programming, embedded systems microprocessors. – Galaxy May 26 '19 at 20:03
  • @ybungalobill So this is how you make your own custom jump table? – Galaxy May 26 '19 at 20:13
  • @Galaxy There are several good ways to implement this functionality without using a construct long proven to be harmful. Trust me, I've seen what rookie programmers can do with this nonsense. One of the most unmaintainable pieces of code I encountered in my entire career was based on using this, and not a single well-written piece of code I've ever seen used it. – Carey Gregory May 26 '19 at 20:16
  • 3
    @CareyGregory Yes, there is other ways to implement this functionality, but they may use one or two assembler instructions more. Remember that not every computer is a desktop machine with lots of spare memory and cycles. GCC is also used for micro-controllers – HAL9000 May 26 '19 at 20:58
  • 2
    It is not clear that an indirect `goto` will take care of destructors etc. The manual says you shouldn't pass labels between functions, but even within a single function, there could be sets of braces between the `goto` and the label where variables would normally be destructed but can't be by this mechanism. Be extremely cautious about using it. It was removed from Fortran because it caused trouble (though there it could be used between functions); most people stopped using it in Fortran in the 70s because it lead to unmaintainable code. It would not be a good idea to use it in new code. – Jonathan Leffler May 26 '19 at 21:07
  • 2
    @CareyGregory `No piece of code using a construct like that would ever survive a code review with me` - The labels as values extension is extensively used in the jump table in the by hand optimized [glibc printf](https://github.com/lattera/glibc/blob/master/stdio-common/vfprintf.c#L242). – KamilCuk May 26 '19 at 21:16
  • 2
    @JonathanLeffler Clang refuses make indirect jumps past non-trivial destructors. GCC just ignores that fact and simply fails to call the destructor. https://www.godbolt.org/z/4aXAgZ. – HTNW May 26 '19 at 22:31
  • @HTNW That compiler explorer link is actually a very interesting and useful thing. – Galaxy May 26 '19 at 23:15