Coverage Report

Created: 2025-07-23 08:13

/src/pango/subprojects/glib/glib/glib-init.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Copyright © 2011 Canonical Limited
3
 *
4
 * SPDX-License-Identifier: LGPL-2.1-or-later
5
 *
6
 * This library is free software; you can redistribute it and/or
7
 * modify it under the terms of the GNU Lesser General Public
8
 * License as published by the Free Software Foundation; either
9
 * version 2.1 of the License, or (at your option) any later version.
10
 *
11
 * This library is distributed in the hope that it will be useful, but
12
 * WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14
 * Lesser General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU Lesser General Public
17
 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
18
 *
19
 * Author: Ryan Lortie <desrt@desrt.ca>
20
 */
21
22
#include "config.h"
23
24
#include "glib-init.h"
25
#include "glib-private.h"
26
#include "gmacros.h"
27
#include "gtypes.h"
28
#include "gutils.h"     /* for GDebugKey */
29
#include "gconstructor.h"
30
#include "gconstructorprivate.h"
31
#include "gmem.h"       /* for g_mem_gc_friendly */
32
33
#include <string.h>
34
#include <stdlib.h>
35
#include <stdio.h>
36
#include <ctype.h>
37
38
/* Deliberately not checking HAVE_STDINT_H here: we officially require a
39
 * C99 toolchain, which implies <stdint.h>, int8_t and so on. If your
40
 * toolchain does not have this, now would be a good time to upgrade. */
41
#include <stdint.h>
42
43
/* This seems as good a place as any to make static assertions about platform
44
 * assumptions we make throughout GLib. */
45
46
/* Test that private macro G_SIGNEDNESS_OF() works as intended */
47
G_STATIC_ASSERT (G_SIGNEDNESS_OF (int) == 1);
48
G_STATIC_ASSERT (G_SIGNEDNESS_OF (unsigned int) == 0);
49
50
/* We do not support 36-bit bytes or other historical curiosities. */
51
G_STATIC_ASSERT (CHAR_BIT == 8);
52
53
/* We assume that data pointers are the same size as function pointers... */
54
G_STATIC_ASSERT (sizeof (gpointer) == sizeof (GFunc));
55
G_STATIC_ASSERT (G_ALIGNOF (gpointer) == G_ALIGNOF (GFunc));
56
/* ... and that all function pointers are the same size. */
57
G_STATIC_ASSERT (sizeof (GFunc) == sizeof (GCompareDataFunc));
58
G_STATIC_ASSERT (G_ALIGNOF (GFunc) == G_ALIGNOF (GCompareDataFunc));
59
60
/* We assume that "small" enums (those where all values fit in INT32_MIN
61
 * to INT32_MAX) are exactly int-sized. In particular, we assume that if
62
 * an enum has no members that exceed the range of char/short, the
63
 * compiler will make it int-sized anyway, so adding a member later that
64
 * *does* exceed the range of char/short is not an ABI break. */
65
typedef enum {
66
    TEST_CHAR_0 = 0
67
} TestChar;
68
typedef enum {
69
    TEST_SHORT_0 = 0,
70
    TEST_SHORT_256 = 256
71
} TestShort;
72
typedef enum {
73
    TEST_INT32_MIN = G_MININT32,
74
    TEST_INT32_MAX = G_MAXINT32
75
} TestInt;
76
G_STATIC_ASSERT (sizeof (TestChar) == sizeof (int));
77
G_STATIC_ASSERT (sizeof (TestShort) == sizeof (int));
78
G_STATIC_ASSERT (sizeof (TestInt) == sizeof (int));
79
G_STATIC_ASSERT (G_ALIGNOF (TestChar) == G_ALIGNOF (int));
80
G_STATIC_ASSERT (G_ALIGNOF (TestShort) == G_ALIGNOF (int));
81
G_STATIC_ASSERT (G_ALIGNOF (TestInt) == G_ALIGNOF (int));
82
83
G_STATIC_ASSERT (sizeof (gchar) == 1);
84
G_STATIC_ASSERT (sizeof (guchar) == 1);
85
86
/* It is platform-dependent whether gchar is signed or unsigned, so there
87
 * is no assertion here for it */
88
G_STATIC_ASSERT (G_SIGNEDNESS_OF (guchar) == 0);
89
90
G_STATIC_ASSERT (sizeof (gint8) * CHAR_BIT == 8);
91
G_STATIC_ASSERT (sizeof (guint8) * CHAR_BIT == 8);
92
G_STATIC_ASSERT (sizeof (gint16) * CHAR_BIT == 16);
93
G_STATIC_ASSERT (sizeof (guint16) * CHAR_BIT == 16);
94
G_STATIC_ASSERT (sizeof (gint32) * CHAR_BIT == 32);
95
G_STATIC_ASSERT (sizeof (guint32) * CHAR_BIT == 32);
96
G_STATIC_ASSERT (sizeof (gint64) * CHAR_BIT == 64);
97
G_STATIC_ASSERT (sizeof (guint64) * CHAR_BIT == 64);
98
99
G_STATIC_ASSERT (sizeof (void *) == GLIB_SIZEOF_VOID_P);
100
G_STATIC_ASSERT (sizeof (gintptr) == sizeof (void *));
101
G_STATIC_ASSERT (sizeof (guintptr) == sizeof (void *));
102
103
G_STATIC_ASSERT (sizeof (short) == sizeof (gshort));
104
G_STATIC_ASSERT (G_MINSHORT == SHRT_MIN);
105
G_STATIC_ASSERT (G_MAXSHORT == SHRT_MAX);
106
G_STATIC_ASSERT (sizeof (unsigned short) == sizeof (gushort));
107
G_STATIC_ASSERT (G_MAXUSHORT == USHRT_MAX);
108
G_STATIC_ASSERT (G_SIGNEDNESS_OF (gshort) == 1);
109
G_STATIC_ASSERT (G_SIGNEDNESS_OF (gushort) == 0);
110
111
G_STATIC_ASSERT (sizeof (int) == sizeof (gint));
112
G_STATIC_ASSERT (G_MININT == INT_MIN);
113
G_STATIC_ASSERT (G_MAXINT == INT_MAX);
114
G_STATIC_ASSERT (sizeof (unsigned int) == sizeof (guint));
115
G_STATIC_ASSERT (G_MAXUINT == UINT_MAX);
116
G_STATIC_ASSERT (G_SIGNEDNESS_OF (gint) == 1);
117
G_STATIC_ASSERT (G_SIGNEDNESS_OF (guint) == 0);
118
119
G_STATIC_ASSERT (sizeof (long) == GLIB_SIZEOF_LONG);
120
G_STATIC_ASSERT (sizeof (long) == sizeof (glong));
121
G_STATIC_ASSERT (G_MINLONG == LONG_MIN);
122
G_STATIC_ASSERT (G_MAXLONG == LONG_MAX);
123
G_STATIC_ASSERT (sizeof (unsigned long) == sizeof (gulong));
124
G_STATIC_ASSERT (G_MAXULONG == ULONG_MAX);
125
G_STATIC_ASSERT (G_SIGNEDNESS_OF (glong) == 1);
126
G_STATIC_ASSERT (G_SIGNEDNESS_OF (gulong) == 0);
127
128
G_STATIC_ASSERT (G_HAVE_GINT64 == 1);
129
130
G_STATIC_ASSERT (sizeof (size_t) == GLIB_SIZEOF_SIZE_T);
131
/* Not a typo: ssize_t is POSIX, not Standard C, but if it exists then
132
 * it's the same size as size_t. */
133
G_STATIC_ASSERT (sizeof (size_t) == GLIB_SIZEOF_SSIZE_T);
134
G_STATIC_ASSERT (sizeof (gsize) == GLIB_SIZEOF_SSIZE_T);
135
G_STATIC_ASSERT (sizeof (gsize) == sizeof (size_t));
136
G_STATIC_ASSERT (G_MAXSIZE == SIZE_MAX);
137
/* Again this is size_t not ssize_t, because ssize_t is POSIX, not C99 */
138
G_STATIC_ASSERT (sizeof (gssize) == sizeof (size_t));
139
G_STATIC_ASSERT (G_ALIGNOF (gsize) == G_ALIGNOF (size_t));
140
G_STATIC_ASSERT (G_ALIGNOF (gssize) == G_ALIGNOF (size_t));
141
/* We assume that GSIZE_TO_POINTER is reversible by GPOINTER_TO_SIZE
142
 * without losing information.
143
 * However, we do not assume that GPOINTER_TO_SIZE can store an arbitrary
144
 * pointer in a gsize (known to be false on CHERI). */
145
G_STATIC_ASSERT (sizeof (size_t) <= sizeof (void *));
146
G_STATIC_ASSERT (G_SIGNEDNESS_OF (size_t) == 0);
147
G_STATIC_ASSERT (G_SIGNEDNESS_OF (gsize) == 0);
148
G_STATIC_ASSERT (G_SIGNEDNESS_OF (gssize) == 1);
149
150
/* Standard C does not guarantee that size_t is the same as uintptr_t,
151
 * but GLib currently assumes they are the same: see
152
 * <https://gitlab.gnome.org/GNOME/glib/-/issues/2842>.
153
 *
154
 * To enable working on bringup for new architectures these assertions
155
 * can be disabled with -DG_ENABLE_EXPERIMENTAL_ABI_COMPILATION.
156
 *
157
 * FIXME: remove these assertions once the API/ABI has stabilized. */
158
#ifndef G_ENABLE_EXPERIMENTAL_ABI_COMPILATION
159
G_STATIC_ASSERT (sizeof (size_t) == sizeof (uintptr_t));
160
G_STATIC_ASSERT (G_ALIGNOF (size_t) == G_ALIGNOF (uintptr_t));
161
#endif
162
163
/* goffset is always 64-bit, even if off_t is only 32-bit
164
 * (compiling without large-file-support on 32-bit) */
165
G_STATIC_ASSERT (sizeof (goffset) == sizeof (gint64));
166
G_STATIC_ASSERT (G_ALIGNOF (goffset) == G_ALIGNOF (gint64));
167
/* goffset is always signed */
168
G_STATIC_ASSERT (G_SIGNEDNESS_OF (goffset) == 1);
169
170
G_STATIC_ASSERT (sizeof (gfloat) == sizeof (float));
171
G_STATIC_ASSERT (G_ALIGNOF (gfloat) == G_ALIGNOF (float));
172
G_STATIC_ASSERT (sizeof (gdouble) == sizeof (double));
173
G_STATIC_ASSERT (G_ALIGNOF (gdouble) == G_ALIGNOF (double));
174
175
G_STATIC_ASSERT (sizeof (gintptr) == sizeof (intptr_t));
176
G_STATIC_ASSERT (sizeof (guintptr) == sizeof (uintptr_t));
177
G_STATIC_ASSERT (G_ALIGNOF (gintptr) == G_ALIGNOF (intptr_t));
178
G_STATIC_ASSERT (G_ALIGNOF (guintptr) == G_ALIGNOF (uintptr_t));
179
G_STATIC_ASSERT (G_SIGNEDNESS_OF (gintptr) == 1);
180
G_STATIC_ASSERT (G_SIGNEDNESS_OF (guintptr) == 0);
181
G_STATIC_ASSERT (G_SIGNEDNESS_OF (intptr_t) == 1);
182
G_STATIC_ASSERT (G_SIGNEDNESS_OF (uintptr_t) == 0);
183
184
G_STATIC_ASSERT (sizeof (gint8) == sizeof (int8_t));
185
G_STATIC_ASSERT (sizeof (guint8) == sizeof (uint8_t));
186
G_STATIC_ASSERT (G_ALIGNOF (gint8) == G_ALIGNOF (int8_t));
187
G_STATIC_ASSERT (G_ALIGNOF (guint8) == G_ALIGNOF (uint8_t));
188
G_STATIC_ASSERT (G_SIGNEDNESS_OF (gint8) == 1);
189
G_STATIC_ASSERT (G_SIGNEDNESS_OF (guint8) == 0);
190
G_STATIC_ASSERT (G_SIGNEDNESS_OF (int8_t) == 1);
191
G_STATIC_ASSERT (G_SIGNEDNESS_OF (uint8_t) == 0);
192
193
G_STATIC_ASSERT (sizeof (gint16) == sizeof (int16_t));
194
G_STATIC_ASSERT (sizeof (guint16) == sizeof (uint16_t));
195
G_STATIC_ASSERT (G_ALIGNOF (gint16) == G_ALIGNOF (int16_t));
196
G_STATIC_ASSERT (G_ALIGNOF (guint16) == G_ALIGNOF (uint16_t));
197
G_STATIC_ASSERT (G_SIGNEDNESS_OF (int16_t) == 1);
198
G_STATIC_ASSERT (G_SIGNEDNESS_OF (uint16_t) == 0);
199
200
G_STATIC_ASSERT (sizeof (gint32) == sizeof (int32_t));
201
G_STATIC_ASSERT (sizeof (guint32) == sizeof (uint32_t));
202
G_STATIC_ASSERT (G_ALIGNOF (gint32) == G_ALIGNOF (int32_t));
203
G_STATIC_ASSERT (G_ALIGNOF (guint32) == G_ALIGNOF (uint32_t));
204
G_STATIC_ASSERT (G_SIGNEDNESS_OF (gint32) == 1);
205
G_STATIC_ASSERT (G_SIGNEDNESS_OF (guint32) == 0);
206
G_STATIC_ASSERT (G_SIGNEDNESS_OF (int32_t) == 1);
207
G_STATIC_ASSERT (G_SIGNEDNESS_OF (uint32_t) == 0);
208
209
G_STATIC_ASSERT (sizeof (gint64) == sizeof (int64_t));
210
G_STATIC_ASSERT (sizeof (guint64) == sizeof (uint64_t));
211
G_STATIC_ASSERT (G_ALIGNOF (gint64) == G_ALIGNOF (int64_t));
212
G_STATIC_ASSERT (G_ALIGNOF (guint64) == G_ALIGNOF (uint64_t));
213
G_STATIC_ASSERT (G_SIGNEDNESS_OF (gint64) == 1);
214
G_STATIC_ASSERT (G_SIGNEDNESS_OF (guint64) == 0);
215
G_STATIC_ASSERT (G_SIGNEDNESS_OF (int64_t) == 1);
216
G_STATIC_ASSERT (G_SIGNEDNESS_OF (uint64_t) == 0);
217
218
/* C11 §6.7, item 3 allows us to rely on this being allowed */
219
typedef struct Foo Foo;
220
typedef struct Foo Foo;
221
222
/**
223
 * g_mem_gc_friendly:
224
 *
225
 * This variable is %TRUE if the `G_DEBUG` environment variable
226
 * includes the key `gc-friendly`.
227
 */
228
gboolean g_mem_gc_friendly = FALSE;
229
230
GLogLevelFlags g_log_msg_prefix = G_LOG_LEVEL_ERROR | G_LOG_LEVEL_WARNING |
231
                                  G_LOG_LEVEL_CRITICAL | G_LOG_LEVEL_DEBUG;
232
GLogLevelFlags g_log_always_fatal = G_LOG_FATAL_MASK;
233
234
static gboolean
235
debug_key_matches (const gchar *key,
236
                   const gchar *token,
237
                   size_t       length)
238
0
{
239
  /* may not call GLib functions: see note in g_parse_debug_string() */
240
0
  for (; length; length--, key++, token++)
241
0
    {
242
0
      char k = (*key   == '_') ? '-' : tolower (*key  );
243
0
      char t = (*token == '_') ? '-' : tolower (*token);
244
245
0
      if (k != t)
246
0
        return FALSE;
247
0
    }
248
249
0
  return *key == '\0';
250
0
}
251
252
/* The GVariant documentation indirectly says that int is at least 32 bits
253
 * (by saying that b, y, n, q, i, u, h are promoted to int). On any
254
 * reasonable platform, int is in fact *exactly* 32 bits long, because
255
 * otherwise, {signed char, short, int} wouldn't be sufficient to provide
256
 * {int8_t, int16_t, int32_t}. */
257
G_STATIC_ASSERT (sizeof (int) == sizeof (gint32));
258
259
/**
260
 * g_parse_debug_string:
261
 * @string: (nullable): a list of debug options separated by colons, spaces, or
262
 * commas, or %NULL.
263
 * @keys: (array length=nkeys): pointer to an array of #GDebugKey which associate
264
 *     strings with bit flags.
265
 * @nkeys: the number of #GDebugKeys in the array.
266
 *
267
 * Parses a string containing debugging options
268
 * into a %guint containing bit flags. This is used
269
 * within GDK and GTK to parse the debug options passed on the
270
 * command line or through environment variables.
271
 *
272
 * If @string is equal to "all", all flags are set. Any flags
273
 * specified along with "all" in @string are inverted; thus,
274
 * "all,foo,bar" or "foo,bar,all" sets all flags except those
275
 * corresponding to "foo" and "bar".
276
 *
277
 * If @string is equal to "help", all the available keys in @keys
278
 * are printed out to standard error.
279
 *
280
 * Returns: the combined set of bit flags.
281
 */
282
guint
283
g_parse_debug_string  (const gchar     *string,
284
                       const GDebugKey *keys,
285
                       guint            nkeys)
286
0
{
287
0
  guint i;
288
0
  guint result = 0;
289
290
0
  if (string == NULL)
291
0
    return 0;
292
293
  /* this function is used during the initialisation of gmessages, gmem
294
   * and gslice, so it may not do anything that causes memory to be
295
   * allocated or risks messages being emitted.
296
   *
297
   * this means, more or less, that this code may not call anything
298
   * inside GLib.
299
   */
300
301
0
  if (!strcasecmp (string, "help"))
302
0
    {
303
      /* using stdio directly for the reason stated above */
304
0
      fprintf (stderr, "Supported debug values:");
305
0
      for (i = 0; i < nkeys; i++)
306
0
        fprintf (stderr, " %s", keys[i].key);
307
0
      fprintf (stderr, " all help\n");
308
0
    }
309
0
  else
310
0
    {
311
0
      const gchar *p = string;
312
0
      const gchar *q;
313
0
      gboolean invert = FALSE;
314
315
0
      while (*p)
316
0
       {
317
0
         q = strpbrk (p, ":;, \t");
318
0
         if (!q)
319
0
           q = p + strlen (p);
320
321
0
         if (debug_key_matches ("all", p, q - p))
322
0
           {
323
0
             invert = TRUE;
324
0
           }
325
0
         else
326
0
           {
327
0
             for (i = 0; i < nkeys; i++)
328
0
               if (debug_key_matches (keys[i].key, p, q - p))
329
0
                 result |= keys[i].value;
330
0
           }
331
332
0
         p = q;
333
0
         if (*p)
334
0
           p++;
335
0
       }
336
337
0
      if (invert)
338
0
        {
339
0
          guint all_flags = 0;
340
341
0
          for (i = 0; i < nkeys; i++)
342
0
            all_flags |= keys[i].value;
343
344
0
          result = all_flags & (~result);
345
0
        }
346
0
    }
347
348
0
  return result;
349
0
}
350
351
static guint
352
g_parse_debug_envvar (const gchar     *envvar,
353
                      const GDebugKey *keys,
354
                      gint             n_keys,
355
                      guint            default_value)
356
24
{
357
24
  const gchar *value;
358
359
#ifdef OS_WIN32
360
  /* "fatal-warnings,fatal-criticals,all,help" is pretty short */
361
  gchar buffer[100];
362
363
  if (GetEnvironmentVariable (envvar, buffer, 100) < 100)
364
    value = buffer;
365
  else
366
    return 0;
367
#else
368
24
  value = getenv (envvar);
369
24
#endif
370
371
24
  if (value == NULL)
372
24
    return default_value;
373
374
0
  return g_parse_debug_string (value, keys, n_keys);
375
24
}
376
377
static void
378
g_messages_prefixed_init (void)
379
12
{
380
12
  const GDebugKey keys[] = {
381
12
    { "error", G_LOG_LEVEL_ERROR },
382
12
    { "critical", G_LOG_LEVEL_CRITICAL },
383
12
    { "warning", G_LOG_LEVEL_WARNING },
384
12
    { "message", G_LOG_LEVEL_MESSAGE },
385
12
    { "info", G_LOG_LEVEL_INFO },
386
12
    { "debug", G_LOG_LEVEL_DEBUG }
387
12
  };
388
389
12
  g_log_msg_prefix = g_parse_debug_envvar ("G_MESSAGES_PREFIXED", keys, G_N_ELEMENTS (keys), g_log_msg_prefix);
390
12
}
391
392
static void
393
g_debug_init (void)
394
12
{
395
12
  const GDebugKey keys[] = {
396
12
    { "gc-friendly", 1 },
397
12
    {"fatal-warnings",  G_LOG_LEVEL_WARNING | G_LOG_LEVEL_CRITICAL },
398
12
    {"fatal-criticals", G_LOG_LEVEL_CRITICAL }
399
12
  };
400
12
  GLogLevelFlags flags;
401
402
12
  flags = g_parse_debug_envvar ("G_DEBUG", keys, G_N_ELEMENTS (keys), 0);
403
404
12
  g_log_always_fatal |= flags & G_LOG_LEVEL_MASK;
405
406
12
  g_mem_gc_friendly = flags & 1;
407
12
}
408
409
void
410
glib_init (void)
411
24
{
412
24
  static gboolean glib_inited;
413
414
24
  if (glib_inited)
415
12
    return;
416
417
12
  glib_inited = TRUE;
418
419
12
  g_messages_prefixed_init ();
420
12
  g_debug_init ();
421
12
  g_quark_init ();
422
12
  g_error_init ();
423
12
}
424
425
#ifdef G_PLATFORM_WIN32
426
427
HMODULE glib_dll = NULL;
428
void glib_win32_init (void);
429
430
void
431
glib_win32_init (void)
432
{
433
  /* May be called more than once in static compilation mode */
434
  static gboolean win32_already_init = FALSE;
435
  if (!win32_already_init)
436
    {
437
      win32_already_init = TRUE;
438
439
      g_crash_handler_win32_init ();
440
#ifdef THREADS_WIN32
441
      g_thread_win32_init ();
442
#endif
443
444
      g_clock_win32_init ();
445
      glib_init ();
446
      /* must go after glib_init */
447
      g_console_win32_init ();
448
    }
449
}
450
451
static void
452
glib_win32_deinit (gboolean detach_thread)
453
{
454
#ifdef THREADS_WIN32
455
  if (detach_thread)
456
    g_thread_win32_process_detach ();
457
#endif
458
  g_crash_handler_win32_deinit ();
459
}
460
461
#ifdef G_DEFINE_CONSTRUCTOR_NEEDS_PRAGMA
462
#pragma G_DEFINE_CONSTRUCTOR_PRAGMA_ARGS(glib_priv_constructor)
463
#endif
464
465
static gboolean tls_callback_invoked;
466
467
G_DEFINE_CONSTRUCTOR (glib_priv_constructor)
468
469
static void
470
glib_priv_constructor (void)
471
{
472
  glib_win32_init ();
473
474
  if (!tls_callback_invoked)
475
    g_critical ("TLS callback not invoked");
476
}
477
478
#ifndef G_HAS_TLS_CALLBACKS
479
#error Compilation on Windows requires TLS callbacks support
480
#endif
481
482
G_DEFINE_TLS_CALLBACK (glib_priv_tls_callback)
483
484
static void NTAPI
485
glib_priv_tls_callback (LPVOID hinstance,
486
                        DWORD  reason,
487
                        LPVOID reserved)
488
{
489
  switch (reason)
490
    {
491
    case DLL_PROCESS_ATTACH:
492
      glib_dll = hinstance;
493
      tls_callback_invoked = TRUE;
494
      break;
495
    case DLL_THREAD_DETACH:
496
#ifdef THREADS_WIN32
497
      g_thread_win32_thread_detach ();
498
#endif
499
      break;
500
    case DLL_PROCESS_DETACH:
501
      glib_win32_deinit (reserved == NULL);
502
      break;
503
504
    default:
505
      break;
506
    }
507
}
508
509
#elif defined(G_HAS_CONSTRUCTORS) /* && !G_PLATFORM_WIN32 */
510
511
#ifdef G_DEFINE_CONSTRUCTOR_NEEDS_PRAGMA
512
#pragma G_DEFINE_CONSTRUCTOR_PRAGMA_ARGS(glib_init_ctor)
513
#endif
514
G_DEFINE_CONSTRUCTOR(glib_init_ctor)
515
516
static void
517
glib_init_ctor (void)
518
12
{
519
12
  glib_init ();
520
12
}
521
522
#else /* !G_PLATFORM_WIN32 && !G_HAS_CONSTRUCTORS */
523
# error Your platform/compiler is missing constructor support
524
#endif /* G_PLATFORM_WIN32 */