Created
February 16, 2019 17:26
-
-
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.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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