diff --git a/expanded.c b/expanded.c new file mode 100644 index 0000000..3f965f0 --- /dev/null +++ b/expanded.c @@ -0,0 +1,31 @@ +#include + +enum HANDLE_STATE { + HANDLE_CREAT, + HANDLE_DESTR +}; + +struct Meaning { + int a; + int b; +}; + +static inline void Meaning_lifetime_handler(enum HANDLE_STATE state, struct Meaning *this, void *data) { + if(state == HANDLE_CREAT) { + this->a = *(int*) data; + this->b = 2; + } else { + printf("%d\n", this->a + this->b); + } +} + + + +int main() { + int initializer = 40; + [[gnu::always_inline]] inline void F(struct Meaning *v) { Meaning_lifetime_handler(HANDLE_DESTR, v, +((void *)0) +); } [[gnu::cleanup(F)]] struct Meaning d; Meaning_lifetime_handler(HANDLE_CREAT, & d, &initializer);; + + return 0; +} diff --git a/handle.h b/handle.h index 2d29b23..b61c2d5 100644 --- a/handle.h +++ b/handle.h @@ -8,24 +8,34 @@ /** Tells your constructor/destructor handler function about the state */ enum HANDLE_STATE { HANDLE_CREAT, - HANDLE_DESTR, + HANDLE_DESTR }; -/** - * This creates a "handle". Basically a struct with given constructor and destructor + RAII. - * - * Usage: +#define creat(TNAME, VNAME, VINIT) \ + [[gnu::always_inline]] inline void VNAME##_cleanuper(struct TNAME *v) { \ + TNAME##_lifetime_handler(HANDLE_DESTR, v, NULL); \ + } \ + [[gnu::cleanup(VNAME##_cleanuper)]] struct TNAME VNAME; \ + TNAME##_lifetime_handler(HANDLE_CREAT, & VNAME, VINIT); + +#define handle(TNAME) \ + static inline void TNAME##_lifetime_handler( \ + enum HANDLE_STATE state, \ + struct TNAME *this, \ + void *data) +/* + * EXAMPLE: * * struct Meaning { * int a; * int b; * }; - * // You can typedef if you want, change code accordingly! + * // You should not typedef this EVER! * - * handle(struct Meaning) { + * handle(Meaning) { * if(state == HANDLE_CREAT) { * this->a = *(int*) data; - * this->b = 2 + * this->b = 2; * } else { * printf("%d\n", this->a + this->b); * } @@ -35,23 +45,9 @@ enum HANDLE_STATE { * // Should print 42: * int main() { * int initializer = 40; - * creat(struct Data, d, &initializer); + * creat(Meaning, d, &initializer); * } * * Rem.: Unrelated trick, but you can typedef struct A A; // both typedef and forward declare */ - -#define creat(TNAME, VNAME, VINIT) \ - [[gnu::always_inline]] inline void F(TNAME *v) { \ - TNAME##_lifetime_handler(HANDLE_DESTR, v, NULL); \ - } \ - [[gnu::cleanup(F)]] TNAME VNAME; \ - TNAME##_lifetime_handler(HANDLE_CREAT, VNAME, VINIT); - -#define handle(TNAME) \ - static [[gnu::always_inline]] inline void TNAME##_lifetime_handler( \ - HANDLE_STATE state, \ - TNAME *this, \ - void *data) - #endif // MAG_HANDLE_H diff --git a/handle_test.c b/handle_test.c index ec2d54b..4e0850a 100644 --- a/handle_test.c +++ b/handle_test.c @@ -6,11 +6,12 @@ struct Meaning { int b; }; -handle(struct Meaning) { +handle(Meaning) { if(state == HANDLE_CREAT) { this->a = *(int*) data; - this->b = 2 + this->b = 2; } else { + // Destructor printf("%d\n", this->a + this->b); } } @@ -19,7 +20,9 @@ handle(struct Meaning) { // Should print 42: int main() { int initializer = 40; - creat(struct Data, d, &initializer); + creat(Meaning, d, &initializer); + initializer = 20; + creat(Meaning, d2, &initializer); return 0; } diff --git a/handle_test_expanded.c b/handle_test_expanded.c deleted file mode 100644 index af46865..0000000 --- a/handle_test_expanded.c +++ /dev/null @@ -1,845 +0,0 @@ -# 0 "handle_test.c" -# 0 "" -# 0 "" -# 1 "/usr/include/stdc-predef.h" 1 3 4 -# 0 "" 2 -# 1 "handle_test.c" -# 1 "/usr/include/stdio.h" 1 3 4 -# 28 "/usr/include/stdio.h" 3 4 -# 1 "/usr/include/bits/libc-header-start.h" 1 3 4 -# 33 "/usr/include/bits/libc-header-start.h" 3 4 -# 1 "/usr/include/features.h" 1 3 4 -# 415 "/usr/include/features.h" 3 4 -# 1 "/usr/include/features-time64.h" 1 3 4 -# 20 "/usr/include/features-time64.h" 3 4 -# 1 "/usr/include/bits/wordsize.h" 1 3 4 -# 21 "/usr/include/features-time64.h" 2 3 4 -# 1 "/usr/include/bits/timesize.h" 1 3 4 -# 19 "/usr/include/bits/timesize.h" 3 4 -# 1 "/usr/include/bits/wordsize.h" 1 3 4 -# 20 "/usr/include/bits/timesize.h" 2 3 4 -# 22 "/usr/include/features-time64.h" 2 3 4 -# 416 "/usr/include/features.h" 2 3 4 -# 524 "/usr/include/features.h" 3 4 -# 1 "/usr/include/sys/cdefs.h" 1 3 4 -# 730 "/usr/include/sys/cdefs.h" 3 4 -# 1 "/usr/include/bits/wordsize.h" 1 3 4 -# 731 "/usr/include/sys/cdefs.h" 2 3 4 -# 1 "/usr/include/bits/long-double.h" 1 3 4 -# 732 "/usr/include/sys/cdefs.h" 2 3 4 -# 525 "/usr/include/features.h" 2 3 4 -# 548 "/usr/include/features.h" 3 4 -# 1 "/usr/include/gnu/stubs.h" 1 3 4 -# 10 "/usr/include/gnu/stubs.h" 3 4 -# 1 "/usr/include/gnu/stubs-64.h" 1 3 4 -# 11 "/usr/include/gnu/stubs.h" 2 3 4 -# 549 "/usr/include/features.h" 2 3 4 -# 34 "/usr/include/bits/libc-header-start.h" 2 3 4 -# 29 "/usr/include/stdio.h" 2 3 4 - - - - - -# 1 "/usr/lib/gcc/x86_64-pc-linux-gnu/14.2.1/include/stddef.h" 1 3 4 -# 214 "/usr/lib/gcc/x86_64-pc-linux-gnu/14.2.1/include/stddef.h" 3 4 - -# 214 "/usr/lib/gcc/x86_64-pc-linux-gnu/14.2.1/include/stddef.h" 3 4 -typedef long unsigned int size_t; -# 35 "/usr/include/stdio.h" 2 3 4 - - -# 1 "/usr/lib/gcc/x86_64-pc-linux-gnu/14.2.1/include/stdarg.h" 1 3 4 -# 40 "/usr/lib/gcc/x86_64-pc-linux-gnu/14.2.1/include/stdarg.h" 3 4 -typedef __builtin_va_list __gnuc_va_list; -# 38 "/usr/include/stdio.h" 2 3 4 - -# 1 "/usr/include/bits/types.h" 1 3 4 -# 27 "/usr/include/bits/types.h" 3 4 -# 1 "/usr/include/bits/wordsize.h" 1 3 4 -# 28 "/usr/include/bits/types.h" 2 3 4 -# 1 "/usr/include/bits/timesize.h" 1 3 4 -# 19 "/usr/include/bits/timesize.h" 3 4 -# 1 "/usr/include/bits/wordsize.h" 1 3 4 -# 20 "/usr/include/bits/timesize.h" 2 3 4 -# 29 "/usr/include/bits/types.h" 2 3 4 - - -typedef unsigned char __u_char; -typedef unsigned short int __u_short; -typedef unsigned int __u_int; -typedef unsigned long int __u_long; - - -typedef signed char __int8_t; -typedef unsigned char __uint8_t; -typedef signed short int __int16_t; -typedef unsigned short int __uint16_t; -typedef signed int __int32_t; -typedef unsigned int __uint32_t; - -typedef signed long int __int64_t; -typedef unsigned long int __uint64_t; - - - - - - -typedef __int8_t __int_least8_t; -typedef __uint8_t __uint_least8_t; -typedef __int16_t __int_least16_t; -typedef __uint16_t __uint_least16_t; -typedef __int32_t __int_least32_t; -typedef __uint32_t __uint_least32_t; -typedef __int64_t __int_least64_t; -typedef __uint64_t __uint_least64_t; - - - -typedef long int __quad_t; -typedef unsigned long int __u_quad_t; - - - - - - - -typedef long int __intmax_t; -typedef unsigned long int __uintmax_t; -# 141 "/usr/include/bits/types.h" 3 4 -# 1 "/usr/include/bits/typesizes.h" 1 3 4 -# 142 "/usr/include/bits/types.h" 2 3 4 -# 1 "/usr/include/bits/time64.h" 1 3 4 -# 143 "/usr/include/bits/types.h" 2 3 4 - - -typedef unsigned long int __dev_t; -typedef unsigned int __uid_t; -typedef unsigned int __gid_t; -typedef unsigned long int __ino_t; -typedef unsigned long int __ino64_t; -typedef unsigned int __mode_t; -typedef unsigned long int __nlink_t; -typedef long int __off_t; -typedef long int __off64_t; -typedef int __pid_t; -typedef struct { int __val[2]; } __fsid_t; -typedef long int __clock_t; -typedef unsigned long int __rlim_t; -typedef unsigned long int __rlim64_t; -typedef unsigned int __id_t; -typedef long int __time_t; -typedef unsigned int __useconds_t; -typedef long int __suseconds_t; -typedef long int __suseconds64_t; - -typedef int __daddr_t; -typedef int __key_t; - - -typedef int __clockid_t; - - -typedef void * __timer_t; - - -typedef long int __blksize_t; - - - - -typedef long int __blkcnt_t; -typedef long int __blkcnt64_t; - - -typedef unsigned long int __fsblkcnt_t; -typedef unsigned long int __fsblkcnt64_t; - - -typedef unsigned long int __fsfilcnt_t; -typedef unsigned long int __fsfilcnt64_t; - - -typedef long int __fsword_t; - -typedef long int __ssize_t; - - -typedef long int __syscall_slong_t; - -typedef unsigned long int __syscall_ulong_t; - - - -typedef __off64_t __loff_t; -typedef char *__caddr_t; - - -typedef long int __intptr_t; - - -typedef unsigned int __socklen_t; - - - - -typedef int __sig_atomic_t; -# 40 "/usr/include/stdio.h" 2 3 4 -# 1 "/usr/include/bits/types/__fpos_t.h" 1 3 4 - - - - -# 1 "/usr/include/bits/types/__mbstate_t.h" 1 3 4 -# 13 "/usr/include/bits/types/__mbstate_t.h" 3 4 -typedef struct -{ - int __count; - union - { - unsigned int __wch; - char __wchb[4]; - } __value; -} __mbstate_t; -# 6 "/usr/include/bits/types/__fpos_t.h" 2 3 4 - - - - -typedef struct _G_fpos_t -{ - __off_t __pos; - __mbstate_t __state; -} __fpos_t; -# 41 "/usr/include/stdio.h" 2 3 4 -# 1 "/usr/include/bits/types/__fpos64_t.h" 1 3 4 -# 10 "/usr/include/bits/types/__fpos64_t.h" 3 4 -typedef struct _G_fpos64_t -{ - __off64_t __pos; - __mbstate_t __state; -} __fpos64_t; -# 42 "/usr/include/stdio.h" 2 3 4 -# 1 "/usr/include/bits/types/__FILE.h" 1 3 4 - - - -struct _IO_FILE; -typedef struct _IO_FILE __FILE; -# 43 "/usr/include/stdio.h" 2 3 4 -# 1 "/usr/include/bits/types/FILE.h" 1 3 4 - - - -struct _IO_FILE; - - -typedef struct _IO_FILE FILE; -# 44 "/usr/include/stdio.h" 2 3 4 -# 1 "/usr/include/bits/types/struct_FILE.h" 1 3 4 -# 36 "/usr/include/bits/types/struct_FILE.h" 3 4 -struct _IO_FILE; -struct _IO_marker; -struct _IO_codecvt; -struct _IO_wide_data; - - - - -typedef void _IO_lock_t; - - - - - -struct _IO_FILE -{ - int _flags; - - - char *_IO_read_ptr; - char *_IO_read_end; - char *_IO_read_base; - char *_IO_write_base; - char *_IO_write_ptr; - char *_IO_write_end; - char *_IO_buf_base; - char *_IO_buf_end; - - - char *_IO_save_base; - char *_IO_backup_base; - char *_IO_save_end; - - struct _IO_marker *_markers; - - struct _IO_FILE *_chain; - - int _fileno; - int _flags2:24; - - char _short_backupbuf[1]; - __off_t _old_offset; - - - unsigned short _cur_column; - signed char _vtable_offset; - char _shortbuf[1]; - - _IO_lock_t *_lock; - - - - - - - - __off64_t _offset; - - struct _IO_codecvt *_codecvt; - struct _IO_wide_data *_wide_data; - struct _IO_FILE *_freeres_list; - void *_freeres_buf; - struct _IO_FILE **_prevchain; - int _mode; - - char _unused2[15 * sizeof (int) - 5 * sizeof (void *)]; -}; -# 45 "/usr/include/stdio.h" 2 3 4 - - -# 1 "/usr/include/bits/types/cookie_io_functions_t.h" 1 3 4 -# 27 "/usr/include/bits/types/cookie_io_functions_t.h" 3 4 -typedef __ssize_t cookie_read_function_t (void *__cookie, char *__buf, - size_t __nbytes); - - - - - - - -typedef __ssize_t cookie_write_function_t (void *__cookie, const char *__buf, - size_t __nbytes); - - - - - - - -typedef int cookie_seek_function_t (void *__cookie, __off64_t *__pos, int __w); - - -typedef int cookie_close_function_t (void *__cookie); - - - - - - -typedef struct _IO_cookie_io_functions_t -{ - cookie_read_function_t *read; - cookie_write_function_t *write; - cookie_seek_function_t *seek; - cookie_close_function_t *close; -} cookie_io_functions_t; -# 48 "/usr/include/stdio.h" 2 3 4 - - - - - -typedef __gnuc_va_list va_list; -# 64 "/usr/include/stdio.h" 3 4 -typedef __off_t off_t; -# 78 "/usr/include/stdio.h" 3 4 -typedef __ssize_t ssize_t; - - - - - - -typedef __fpos_t fpos_t; -# 129 "/usr/include/stdio.h" 3 4 -# 1 "/usr/include/bits/stdio_lim.h" 1 3 4 -# 130 "/usr/include/stdio.h" 2 3 4 -# 149 "/usr/include/stdio.h" 3 4 -extern FILE *stdin; -extern FILE *stdout; -extern FILE *stderr; - - - - - - -extern int remove (const char *__filename) __attribute__ ((__nothrow__ , __leaf__)); - -extern int rename (const char *__old, const char *__new) __attribute__ ((__nothrow__ , __leaf__)); - - - -extern int renameat (int __oldfd, const char *__old, int __newfd, - const char *__new) __attribute__ ((__nothrow__ , __leaf__)); -# 184 "/usr/include/stdio.h" 3 4 -extern int fclose (FILE *__stream) __attribute__ ((__nonnull__ (1))); -# 194 "/usr/include/stdio.h" 3 4 -extern FILE *tmpfile (void) - __attribute__ ((__malloc__)) __attribute__ ((__malloc__ (fclose, 1))) ; -# 211 "/usr/include/stdio.h" 3 4 -extern char *tmpnam (char[20]) __attribute__ ((__nothrow__ , __leaf__)) ; - - - - -extern char *tmpnam_r (char __s[20]) __attribute__ ((__nothrow__ , __leaf__)) ; -# 228 "/usr/include/stdio.h" 3 4 -extern char *tempnam (const char *__dir, const char *__pfx) - __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__malloc__)) __attribute__ ((__malloc__ (__builtin_free, 1))); - - - - - - -extern int fflush (FILE *__stream); -# 245 "/usr/include/stdio.h" 3 4 -extern int fflush_unlocked (FILE *__stream); -# 264 "/usr/include/stdio.h" 3 4 -extern FILE *fopen (const char *__restrict __filename, - const char *__restrict __modes) - __attribute__ ((__malloc__)) __attribute__ ((__malloc__ (fclose, 1))) ; - - - - -extern FILE *freopen (const char *__restrict __filename, - const char *__restrict __modes, - FILE *__restrict __stream) __attribute__ ((__nonnull__ (3))); -# 299 "/usr/include/stdio.h" 3 4 -extern FILE *fdopen (int __fd, const char *__modes) __attribute__ ((__nothrow__ , __leaf__)) - __attribute__ ((__malloc__)) __attribute__ ((__malloc__ (fclose, 1))) ; - - - - - -extern FILE *fopencookie (void *__restrict __magic_cookie, - const char *__restrict __modes, - cookie_io_functions_t __io_funcs) __attribute__ ((__nothrow__ , __leaf__)) - __attribute__ ((__malloc__)) __attribute__ ((__malloc__ (fclose, 1))) ; - - - - -extern FILE *fmemopen (void *__s, size_t __len, const char *__modes) - __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__malloc__)) __attribute__ ((__malloc__ (fclose, 1))) ; - - - - -extern FILE *open_memstream (char **__bufloc, size_t *__sizeloc) __attribute__ ((__nothrow__ , __leaf__)) - __attribute__ ((__malloc__)) __attribute__ ((__malloc__ (fclose, 1))) ; -# 334 "/usr/include/stdio.h" 3 4 -extern void setbuf (FILE *__restrict __stream, char *__restrict __buf) __attribute__ ((__nothrow__ , __leaf__)) - __attribute__ ((__nonnull__ (1))); - - - -extern int setvbuf (FILE *__restrict __stream, char *__restrict __buf, - int __modes, size_t __n) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1))); - - - - -extern void setbuffer (FILE *__restrict __stream, char *__restrict __buf, - size_t __size) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1))); - - -extern void setlinebuf (FILE *__stream) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1))); - - - - - - - -extern int fprintf (FILE *__restrict __stream, - const char *__restrict __format, ...) __attribute__ ((__nonnull__ (1))); - - - - -extern int printf (const char *__restrict __format, ...); - -extern int sprintf (char *__restrict __s, - const char *__restrict __format, ...) __attribute__ ((__nothrow__)); - - - - - -extern int vfprintf (FILE *__restrict __s, const char *__restrict __format, - __gnuc_va_list __arg) __attribute__ ((__nonnull__ (1))); - - - - -extern int vprintf (const char *__restrict __format, __gnuc_va_list __arg); - -extern int vsprintf (char *__restrict __s, const char *__restrict __format, - __gnuc_va_list __arg) __attribute__ ((__nothrow__)); - - - -extern int snprintf (char *__restrict __s, size_t __maxlen, - const char *__restrict __format, ...) - __attribute__ ((__nothrow__)) __attribute__ ((__format__ (__printf__, 3, 4))); - -extern int vsnprintf (char *__restrict __s, size_t __maxlen, - const char *__restrict __format, __gnuc_va_list __arg) - __attribute__ ((__nothrow__)) __attribute__ ((__format__ (__printf__, 3, 0))); - - - - - -extern int vasprintf (char **__restrict __ptr, const char *__restrict __f, - __gnuc_va_list __arg) - __attribute__ ((__nothrow__)) __attribute__ ((__format__ (__printf__, 2, 0))) ; -extern int __asprintf (char **__restrict __ptr, - const char *__restrict __fmt, ...) - __attribute__ ((__nothrow__)) __attribute__ ((__format__ (__printf__, 2, 3))) ; -extern int asprintf (char **__restrict __ptr, - const char *__restrict __fmt, ...) - __attribute__ ((__nothrow__)) __attribute__ ((__format__ (__printf__, 2, 3))) ; - - - - -extern int vdprintf (int __fd, const char *__restrict __fmt, - __gnuc_va_list __arg) - __attribute__ ((__format__ (__printf__, 2, 0))); -extern int dprintf (int __fd, const char *__restrict __fmt, ...) - __attribute__ ((__format__ (__printf__, 2, 3))); - - - - - - - -extern int fscanf (FILE *__restrict __stream, - const char *__restrict __format, ...) __attribute__ ((__nonnull__ (1))); - - - - -extern int scanf (const char *__restrict __format, ...) ; - -extern int sscanf (const char *__restrict __s, - const char *__restrict __format, ...) __attribute__ ((__nothrow__ , __leaf__)); - - - - - -# 1 "/usr/include/bits/floatn.h" 1 3 4 -# 131 "/usr/include/bits/floatn.h" 3 4 -# 1 "/usr/include/bits/floatn-common.h" 1 3 4 -# 24 "/usr/include/bits/floatn-common.h" 3 4 -# 1 "/usr/include/bits/long-double.h" 1 3 4 -# 25 "/usr/include/bits/floatn-common.h" 2 3 4 -# 132 "/usr/include/bits/floatn.h" 2 3 4 -# 438 "/usr/include/stdio.h" 2 3 4 -# 463 "/usr/include/stdio.h" 3 4 -extern int fscanf (FILE *__restrict __stream, const char *__restrict __format, ...) __asm__ ("" "__isoc99_fscanf") - - __attribute__ ((__nonnull__ (1))); -extern int scanf (const char *__restrict __format, ...) __asm__ ("" "__isoc99_scanf") - ; -extern int sscanf (const char *__restrict __s, const char *__restrict __format, ...) __asm__ ("" "__isoc99_sscanf") __attribute__ ((__nothrow__ , __leaf__)) - - ; -# 490 "/usr/include/stdio.h" 3 4 -extern int vfscanf (FILE *__restrict __s, const char *__restrict __format, - __gnuc_va_list __arg) - __attribute__ ((__format__ (__scanf__, 2, 0))) __attribute__ ((__nonnull__ (1))); - - - - - -extern int vscanf (const char *__restrict __format, __gnuc_va_list __arg) - __attribute__ ((__format__ (__scanf__, 1, 0))) ; - - -extern int vsscanf (const char *__restrict __s, - const char *__restrict __format, __gnuc_va_list __arg) - __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__format__ (__scanf__, 2, 0))); -# 540 "/usr/include/stdio.h" 3 4 -extern int vfscanf (FILE *__restrict __s, const char *__restrict __format, __gnuc_va_list __arg) __asm__ ("" "__isoc99_vfscanf") - - - - __attribute__ ((__format__ (__scanf__, 2, 0))) __attribute__ ((__nonnull__ (1))); -extern int vscanf (const char *__restrict __format, __gnuc_va_list __arg) __asm__ ("" "__isoc99_vscanf") - - __attribute__ ((__format__ (__scanf__, 1, 0))) ; -extern int vsscanf (const char *__restrict __s, const char *__restrict __format, __gnuc_va_list __arg) __asm__ ("" "__isoc99_vsscanf") __attribute__ ((__nothrow__ , __leaf__)) - - - - __attribute__ ((__format__ (__scanf__, 2, 0))); -# 575 "/usr/include/stdio.h" 3 4 -extern int fgetc (FILE *__stream) __attribute__ ((__nonnull__ (1))); -extern int getc (FILE *__stream) __attribute__ ((__nonnull__ (1))); - - - - - -extern int getchar (void); - - - - - - -extern int getc_unlocked (FILE *__stream) __attribute__ ((__nonnull__ (1))); -extern int getchar_unlocked (void); -# 600 "/usr/include/stdio.h" 3 4 -extern int fgetc_unlocked (FILE *__stream) __attribute__ ((__nonnull__ (1))); -# 611 "/usr/include/stdio.h" 3 4 -extern int fputc (int __c, FILE *__stream) __attribute__ ((__nonnull__ (2))); -extern int putc (int __c, FILE *__stream) __attribute__ ((__nonnull__ (2))); - - - - - -extern int putchar (int __c); -# 627 "/usr/include/stdio.h" 3 4 -extern int fputc_unlocked (int __c, FILE *__stream) __attribute__ ((__nonnull__ (2))); - - - - - - - -extern int putc_unlocked (int __c, FILE *__stream) __attribute__ ((__nonnull__ (2))); -extern int putchar_unlocked (int __c); - - - - - - -extern int getw (FILE *__stream) __attribute__ ((__nonnull__ (1))); - - -extern int putw (int __w, FILE *__stream) __attribute__ ((__nonnull__ (2))); - - - - - - - -extern char *fgets (char *__restrict __s, int __n, FILE *__restrict __stream) - __attribute__ ((__access__ (__write_only__, 1, 2))) __attribute__ ((__nonnull__ (3))); -# 689 "/usr/include/stdio.h" 3 4 -extern __ssize_t __getdelim (char **__restrict __lineptr, - size_t *__restrict __n, int __delimiter, - FILE *__restrict __stream) __attribute__ ((__nonnull__ (4))); -extern __ssize_t getdelim (char **__restrict __lineptr, - size_t *__restrict __n, int __delimiter, - FILE *__restrict __stream) __attribute__ ((__nonnull__ (4))); - - -extern __ssize_t getline (char **__restrict __lineptr, - size_t *__restrict __n, - FILE *__restrict __stream) __attribute__ ((__nonnull__ (3))); - - - - - - - -extern int fputs (const char *__restrict __s, FILE *__restrict __stream) - __attribute__ ((__nonnull__ (2))); - - - - - -extern int puts (const char *__s); - - - - - - -extern int ungetc (int __c, FILE *__stream) __attribute__ ((__nonnull__ (2))); - - - - - - -extern size_t fread (void *__restrict __ptr, size_t __size, - size_t __n, FILE *__restrict __stream) - __attribute__ ((__nonnull__ (4))); - - - - -extern size_t fwrite (const void *__restrict __ptr, size_t __size, - size_t __n, FILE *__restrict __s) __attribute__ ((__nonnull__ (4))); -# 756 "/usr/include/stdio.h" 3 4 -extern size_t fread_unlocked (void *__restrict __ptr, size_t __size, - size_t __n, FILE *__restrict __stream) - __attribute__ ((__nonnull__ (4))); -extern size_t fwrite_unlocked (const void *__restrict __ptr, size_t __size, - size_t __n, FILE *__restrict __stream) - __attribute__ ((__nonnull__ (4))); - - - - - - - -extern int fseek (FILE *__stream, long int __off, int __whence) - __attribute__ ((__nonnull__ (1))); - - - - -extern long int ftell (FILE *__stream) __attribute__ ((__nonnull__ (1))); - - - - -extern void rewind (FILE *__stream) __attribute__ ((__nonnull__ (1))); -# 793 "/usr/include/stdio.h" 3 4 -extern int fseeko (FILE *__stream, __off_t __off, int __whence) - __attribute__ ((__nonnull__ (1))); - - - - -extern __off_t ftello (FILE *__stream) __attribute__ ((__nonnull__ (1))); -# 819 "/usr/include/stdio.h" 3 4 -extern int fgetpos (FILE *__restrict __stream, fpos_t *__restrict __pos) - __attribute__ ((__nonnull__ (1))); - - - - -extern int fsetpos (FILE *__stream, const fpos_t *__pos) __attribute__ ((__nonnull__ (1))); -# 850 "/usr/include/stdio.h" 3 4 -extern void clearerr (FILE *__stream) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1))); - -extern int feof (FILE *__stream) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1))); - -extern int ferror (FILE *__stream) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1))); - - - -extern void clearerr_unlocked (FILE *__stream) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1))); -extern int feof_unlocked (FILE *__stream) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1))); -extern int ferror_unlocked (FILE *__stream) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1))); - - - - - - - -extern void perror (const char *__s) __attribute__ ((__cold__)); - - - - -extern int fileno (FILE *__stream) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1))); - - - - -extern int fileno_unlocked (FILE *__stream) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1))); -# 887 "/usr/include/stdio.h" 3 4 -extern int pclose (FILE *__stream) __attribute__ ((__nonnull__ (1))); - - - - - -extern FILE *popen (const char *__command, const char *__modes) - __attribute__ ((__malloc__)) __attribute__ ((__malloc__ (pclose, 1))) ; - - - - - - -extern char *ctermid (char *__s) __attribute__ ((__nothrow__ , __leaf__)) - __attribute__ ((__access__ (__write_only__, 1))); -# 931 "/usr/include/stdio.h" 3 4 -extern void flockfile (FILE *__stream) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1))); - - - -extern int ftrylockfile (FILE *__stream) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1))); - - -extern void funlockfile (FILE *__stream) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1))); -# 949 "/usr/include/stdio.h" 3 4 -extern int __uflow (FILE *); -extern int __overflow (FILE *, int); -# 973 "/usr/include/stdio.h" 3 4 - -# 2 "handle_test.c" 2 -# 1 "handle.h" 1 -# 9 "handle.h" - -# 9 "handle.h" -enum HANDLE_STATE { - HANDLE_CREAT, - HANDLE_DESTR, -}; -# 3 "handle_test.c" 2 - -struct Meaning { - int a; - int b; -}; - -static [[gnu::always_inline]] inline void struct Meaning_lifetime_handler( HANDLE_STATE state, struct Meaning *this, void *data) { - if(state == HANDLE_CREAT) { - this->a = *(int*) data; - this->b = 2 - } else { - printf("%d\n", this->a + this->b); - } -} - - - -int main() { - int initializer = 40; - [[gnu::always_inline]] inline void F(struct Data *v) { struct Data_lifetime_handler(HANDLE_DESTR, v, -# 22 "handle_test.c" 3 4 -((void *)0) -# 22 "handle_test.c" -); } [[gnu::cleanup(F)]] struct Data d; struct Data_lifetime_handler(HANDLE_CREAT, d, &initializer);; - - return 0; -}