Skip to content

Instantly share code, notes, and snippets.

@wataash
Last active April 18, 2022 14:52
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save wataash/447decc4fc4041de79c3d574edd53000 to your computer and use it in GitHub Desktop.
Save wataash/447decc4fc4041de79c3d574edd53000 to your computer and use it in GitHub Desktop.
Anonymous functions in C (Cで匿名関数)
#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);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment