Stroika Library 3.0d16
 
Loading...
Searching...
No Matches
CompileTimeFlagChecker.h
Go to the documentation of this file.
1/*
2 * Copyright(c) Sophist Solutions, Inc. 1990-2025. All rights reserved
3 */
4#ifndef _Stroika_Foundation_Debug_CompileTimeFlagChecker_h_
5#define _Stroika_Foundation_Debug_CompileTimeFlagChecker_h_ 1
6
7#include "Stroika/Foundation/StroikaPreComp.h"
8
9#include <cstdint>
10
11/**
12 * \file
13 *
14 * \note Code-Status: <a href="Code-Status.md#Beta">Beta</a>
15 *
16 * @todo This is still a pretty weak implementation, so could use some revisiting. But better now
17 * as of Stroika v2.1d18
18 *
19 * @todo Make sure not actually generating code in release builds, but still generating enough code so
20 * we get linker erorr missing qStroika_Foundation_Debug_AssertionsChecked=1/0.
21 *
22 */
23
24namespace Stroika::Foundation::Debug {
25
26 struct CompileTimeFlagChecker {
27 using HiddenValueType = uint8_t;
28 };
29
30 /**
31 * \brief CompileTimeFlagChecker_HEADER () will generate a LINK ERROR if you ever compile a header with one value and
32 * the corresponding CompileTimeFlagChecker_SOURCE () with another value.
33 *
34 * It is HOPED the linker will optimize these references out (else wise - they should be small, not super significant).
35 *
36 * But still hopefully check them so that compiling with mixed CPP defines (-D defines) will cause an easily diagnosic error message.
37 *
38 * If this check fails, you will see a linker message like
39 * \code
40 * unresolved external symbol "unsigned char Stroika::Foundation::Debug::CompileTimeCheck_VARIABLENAME_BADVALUE
41 * \endcode
42 *
43 * \par Example Usage
44 * \code
45 * error LNK2001: unresolved external symbol "unsigned char Stroika::Foundation::Debug::CompileTimeCheck_qTraceToFile_0
46 * \endcode
47 * means that the variable qTraceToFile was defined '0' in some header, but some other value (that would be 1) in the cpp file where Stroika was built.
48 *
49 * \note The CompileTimeFlagChecker_HEADER () must occur in the global namespace (in order to forward declare the shared variable in a specific namespace
50 * given by the first macro argument).
51 *
52 * \par Example Usage
53 * \code
54 * CompileTimeFlagChecker_HEADER (Stroika::Foundation::Debug, qTraceToFile, qTraceToFile);
55 * \endcode
56 *
57 * \note **DEFECT**
58 * The VALUE (third) argument to CompileTimeFlagChecker_HEADER and CompileTimeFlagChecker_SOURCE must expand to zero or one, not
59 * a complex expression due to how the name macro name pasting works. UNDESIRABLE!.
60 */
61#define CompileTimeFlagChecker_HEADER(NS_PREFIX, NAME, VALUE) \
62 CompileTimeCheck_HEADER_INTERNAL_ (NS_PREFIX, CompileTimeChecker_##NAME, CompileTimeCheck_##NAME, VALUE)
63#define CompileTimeCheck_HEADER_INTERNAL_(NS_PREFIX, CHECKERNAME, NAME, VALUE) \
64 namespace NS_PREFIX { \
65 extern Stroika::Foundation::Debug::CompileTimeFlagChecker::HiddenValueType NAME##_##VALUE; \
66 } \
67 namespace { \
68 struct tester_##CHECKERNAME##_ { \
69 tester_##CHECKERNAME##_ () \
70 { \
71 /* just reference given name that will be a link error if header references name not defined in CPP file */ \
72 [[maybe_unused]] Stroika::Foundation::Debug::CompileTimeFlagChecker::HiddenValueType a = NS_PREFIX::NAME##_##VALUE; \
73 }; \
74 }; \
75 tester_##CHECKERNAME##_ t_##CHECKERNAME##_; \
76 }
77
78 /**
79 * \note NS_PREFIX must be the namespace in which the CompileTimeFlagChecker_HEADER was declared.
80 *
81 * Put exactly one of these in a single .cpp file that should be the definition of what everything else must be consistent with.
82 * It should take the same arguments as the corresponding CompileTimeFlagChecker_SOURCE ().
83 *
84 * \par Example Usage
85 * \code
86 * CompileTimeFlagChecker_SOURCE (Stroika::Foundation::Debug, qTraceToFile, qTraceToFile);
87 * \endcode
88 *
89 * \note **DEFECT**
90 * The VALUE (third) argument to CompileTimeFlagChecker_HEADER and CompileTimeFlagChecker_SOURCE must expand to zero or one, not
91 * a complex expression due to how the name macro name pasting works. UNDESIRABLE!.
92 */
93#define CompileTimeFlagChecker_SOURCE(NS_PREFIX, NAME, VALUE) CompileTimeCheck_SOURCE_PRIVATE_1_ (NS_PREFIX, CompileTimeCheck_##NAME, VALUE)
94#define CompileTimeCheck_SOURCE_PRIVATE_1_(NS_PREFIX, NAME, VALUE) \
95 Stroika::Foundation::Debug::CompileTimeFlagChecker::HiddenValueType NS_PREFIX::NAME##_##VALUE = 1;
96
97}
98
99/*
100********************************************************************************
101***************************** Implementation Details ***************************
102********************************************************************************
103*/
104#include "CompileTimeFlagChecker.inl"
105
106#endif /*_Stroika_Foundation_Debug_CompileTimeFlagChecker_h_*/