exp2l: Work around a NetBSD 10.0/i386 bug.
[gnulib.git] / lib / immutable.h
blobc52477138d5d2c592f30b2aab5d98c0e9f4f2438
1 /* Immutable data.
3 Copyright (C) 2021-2024 Free Software Foundation, Inc.
5 This file is free software: you can redistribute it and/or modify
6 it under the terms of the GNU Lesser General Public License as
7 published by the Free Software Foundation; either version 2.1 of the
8 License, or (at your option) any later version.
10 This file is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU Lesser General Public License for more details.
15 You should have received a copy of the GNU Lesser General Public License
16 along with this program. If not, see <https://www.gnu.org/licenses/>. */
18 /* Written by Bruno Haible <bruno@clisp.org>, 2021. */
20 #ifndef _IMMUTABLE_H
21 #define _IMMUTABLE_H
23 /* This file provide a facility to allocate and free immutable data objects.
25 An immutable data object is allocated in three steps:
26 1. You allocate an immutable memory region.
27 DATA *wp = immmalloc (sizeof (*wp));
28 The pointer wp is actually a writable view to the memory region.
29 2. You fill the memory region, through the pointer wp:
30 wp->x = ...;
31 wp->y = ...;
32 ...
33 3. You declare the memory region as frozen. This means that you relinquish
34 write access.
35 DATA const *p = immfreeze (wp);
36 You can now let wp get out-of-scope.
38 Then the pointer p can be used only in read-only ways. That is, if you cast
39 away the 'const' and attempt to write to the memory region, it will crash at
40 runtime (through a SIGSEGV signal).
41 p->x = ...; // rejected by the compiler
42 ((DATA *) p)->x = ...; // crashes at runtime
44 Finally, you can free the immutable data object:
45 immfree (p);
48 /* If you compile this module with the C macro NO_IMMUTABLE set to 1, or on a
49 platform that lacks support for read-only and writeable memory areas, the
50 functions work alike, except that the "read-only" pointers are actually
51 writable. */
53 /* This file uses HAVE_WORKING_MPROTECT. */
54 #if !_GL_CONFIG_H_INCLUDED
55 #error "Please include config.h first."
56 #endif
58 #include <stddef.h>
60 #ifdef __cplusplus
61 extern "C" {
62 #endif
64 /* This macro tells whether the implementation effectively rejects writes to
65 immutable data. */
66 #if !NO_IMMUTABLE && ((defined _WIN32 && !defined __CYGWIN__) || HAVE_WORKING_MPROTECT)
67 # define IMMUTABLE_EFFECTIVE 1
68 #else
69 # define IMMUTABLE_EFFECTIVE 0
70 #endif
72 /* Allocates an immutable memory region.
73 SIZE if the number of bytes; should be > 0.
74 Returns a writeable pointer to the memory region.
75 Upon memory allocation failure, returns NULL with errno set to ENOMEM. */
76 extern void * immmalloc (size_t size);
78 /* Freezes an immutable memory region.
79 WRITABLE_POINTER is a non-NULL return value from immmalloc().
80 Returns a read-only pointer to the same memory region. */
81 extern const void * immfreeze (void *writable_pointer);
83 /* Frees an immutable memory region.
84 READONLY_POINTER is a return value from immfreeze(). */
85 extern void immfree (const void *readonly_pointer);
87 /* The following is just an application to some data types. */
89 /* Allocates an immutable memory region that contains a copy of the given string.
90 Returns a read-only pointer to this duplicated string.
91 Upon memory allocation failure, returns NULL with errno set to ENOMEM. */
92 extern const char * immstrdup (const char *string);
94 #ifdef __cplusplus
96 #endif
98 #endif /* _IMMUTABLE_H */