Using GNU extensions.
Refferences:
| #include <stdio.h> | |
| int main(int argc, char *argv[]) { | |
| int int42 = ({ int _(const char *s) { | |
| printf("lambda: %s\n", s); | |
| return 42; | |
| } _; })("foo"); | |
| const int (*fn)(const char *) = ({ int _(const char *s) { | |
| printf("lambda: %s\n", s); | |
| return 42; | |
| } _; }); | |
| int42 = fn("foo"); | |
| } |
| #include <err.h> | |
| #include <stdlib.h> | |
| #include <stddef.h> | |
| #include <unistd.h> | |
| #include <event2/event.h> | |
| int main(int argc, char *argv[]) { | |
| struct event_base *base = event_base_new(); | |
| if (base == NULL) | |
| err(EXIT_FAILURE, "event_base_new"); | |
| struct event *ev = event_new( | |
| base, | |
| STDIN_FILENO, | |
| EV_READ, | |
| ({ void _(evutil_socket_t fd, short event, void *arg) { | |
| printf("callbacked! %d %hd %p\n", fd, event, arg); | |
| } _; }), | |
| NULL); | |
| if (ev == NULL) | |
| err(EXIT_FAILURE, "event_new"); | |
| struct timeval timeout = {1, 0}; | |
| (void)event_add(ev, &timeout); | |
| (void)event_base_dispatch(base); | |
| event_free(ev); | |
| event_base_free(base); | |
| } |
| #include <err.h> | |
| #include <stdlib.h> | |
| #include <stddef.h> | |
| #include <unistd.h> | |
| #include <event2/event.h> | |
| struct event *event_new_with_anonymous_INVALID(struct event_base *base, evutil_socket_t fd, short events, void *arg) { | |
| struct event *ev = event_new( | |
| base, | |
| fd, | |
| events, | |
| // This argument is passed as a stack variable (at least on x86_64 Linux); | |
| // i.e., will be discarded after returning this function (event_new_with_anonymous_INVALID()). | |
| ({ void _(evutil_socket_t fd, short event, void *arg) { | |
| printf("callbacked! %d %hd %p\n", fd, event, arg); | |
| } _; }), | |
| arg); | |
| if (ev == NULL) | |
| err(EXIT_FAILURE, "event_new"); | |
| return ev; // now the pointer to the anonymous function discarded! | |
| } | |
| int main(int argc, char *argv[]) { | |
| struct event_base *base = event_base_new(); | |
| if (base == NULL) | |
| err(EXIT_FAILURE, "event_base_new"); | |
| const struct event *ev = event_new_with_anonymous_INVALID(base, STDIN_FILENO, EV_READ, NULL); | |
| // The function pointer which ev has is invalid! | |
| struct timeval timeout = {1, 0}; | |
| (void)event_add(ev, &timeout); | |
| (void)event_base_dispatch(base); // SEGV when trying to call anonymous function | |
| event_free(ev); | |
| event_base_free(base); | |
| } |