Skip to content

Instantly share code, notes, and snippets.

@TJesionowski
Created February 16, 2019 17:26
Show Gist options
  • Save TJesionowski/ff4c9d7d3b76ba63139fc9f953e44d2b to your computer and use it in GitHub Desktop.
Save TJesionowski/ff4c9d7d3b76ba63139fc9f953e44d2b to your computer and use it in GitHub Desktop.
An example of parametric gotos, an incredibly weird feature of gcc that lets you do things like intra-function jump tables.
#include <stdio.h>
int main() {
printf("Enter 0 to print hello and 1 to print goodbye: ");
unsigned long mask = 0;
scanf("%ld", &mask);
// ensure mask is 0 or 1
mask = !(!(mask));
// extend first bit to all bits
int i = 0;
mask = mask|(mask << i++);
mask = mask|(mask << i);
i *= 2;
mask = mask|(mask << i);
i *= 2;
mask = mask|(mask << i);
i *= 2;
mask = mask|(mask << i);
i *= 2;
mask = mask|(mask << i);
i *= 2;
mask = mask|(mask << i);
// Load the addresses of the labels. Only works in gcc.
unsigned long h = (unsigned long) &&hello;
unsigned long g = (unsigned long) &&goodbye;
// The mask is either all zeros or all ones, so this will evaulate to one of the addresses,
// which is then passed to a parametric goto
goto *(void *)((h&(~mask)) | (g&mask));
hello:
printf("Hello!\n");
goto end;
goodbye:
printf("Goodbye!\n");
goto end;
end:
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment