1 //
2 // lconv_unsigned_char_initialization.cpp
3 //
4 //      Copyright (c) Microsoft Corporation. All rights reserved.
5 //
6 // lconv initialization used to support an unsigned 'char' type (enabled by the
7 // -J flag during compilation).  Per the specification, some members of the lconv
8 // structure must be initialized to CHAR_MAX.  The value of CHAR_MAX, however,
9 // depends on whether the 'char' type is signed or unsigned (it is 127 for a
10 // signed 'char'; 255 for an unsigned 'char').
11 //
12 // By default, these members of lconv are initialized to SCHAR_MAX (127).  If an
13 // unsigned 'char' type is used, we call this function to update those members
14 // to UCHAR_MAX (255).  Note that this is not done for DLLs that are linked to
15 // the CRT DLL, because we do not want such DLLs to override the -J setting for
16 // an EXE linked to the CRT DLL.
17 //
18 // There is code in several other files that is required to make all of this work:
19 //
20 // * locale.h:  When -J is used to compile a source file that includes <locale.h>,
21 //   it generates an unresolved external to __do_unsigned_char_lconv_initialization.
22 //
23 // * lconv_unsigned_char_static.cpp:  This file defines a global variable named
24 //   __do_unsigned_char_lconv_initialization, and is used during the link to
25 //   satisfy the unresolved external.  This file adds a call to
26 //   __initialize_lconv_for_unsigned_char to the list of initializers to be
27 //   executed.  That function (defined below) updates the fields of the lconv
28 //   structure to be set to UCHAR_MAX.
29 //
30 // * localeconv.cpp:  This file defines the __acrt_lconv_c structure.
31 //
32 #include <corecrt_internal.h>
33 #include <limits.h>
34 #include <locale.h>
35 
36 #pragma warning(disable: 4310) // cast truncates constant value
37 
38 
39 
40 extern "C" int __cdecl __initialize_lconv_for_unsigned_char()
41 {
42     __acrt_lconv_c.int_frac_digits = (char)UCHAR_MAX;
43     __acrt_lconv_c.frac_digits     = (char)UCHAR_MAX;
44     __acrt_lconv_c.p_cs_precedes   = (char)UCHAR_MAX;
45     __acrt_lconv_c.p_sep_by_space  = (char)UCHAR_MAX;
46     __acrt_lconv_c.n_cs_precedes   = (char)UCHAR_MAX;
47     __acrt_lconv_c.n_sep_by_space  = (char)UCHAR_MAX;
48     __acrt_lconv_c.p_sign_posn     = (char)UCHAR_MAX;
49     __acrt_lconv_c.n_sign_posn     = (char)UCHAR_MAX;
50 
51     return 0;
52 }
53