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); | |
} |