VirtualBox

source: vbox/trunk/include/iprt/assertcompile.h@ 76553

Last change on this file since 76553 was 76553, checked in by vboxsync, 6 years ago

scm --update-copyright-year

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 8.2 KB
Line 
1/** @file
2 * IPRT - Compile Time Assertions.
3 */
4
5/*
6 * Copyright (C) 2006-2019 Oracle Corporation
7 *
8 * This file is part of VirtualBox Open Source Edition (OSE), as
9 * available from http://www.virtualbox.org. This file is free software;
10 * you can redistribute it and/or modify it under the terms of the GNU
11 * General Public License (GPL) as published by the Free Software
12 * Foundation, in version 2 as it comes in the "COPYING" file of the
13 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
14 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
15 *
16 * The contents of this file may alternatively be used under the terms
17 * of the Common Development and Distribution License Version 1.0
18 * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
19 * VirtualBox OSE distribution, in which case the provisions of the
20 * CDDL are applicable instead of those of the GPL.
21 *
22 * You may elect to license modified versions of this file under the
23 * terms and conditions of either the GPL or the CDDL or both.
24 */
25
26#ifndef ___iprt_assertcompile_h
27#define ___iprt_assertcompile_h
28#ifndef RT_WITHOUT_PRAGMA_ONCE
29# pragma once
30#endif
31
32#include <iprt/cdefs.h>
33
34/** @defgroup grp_rt_assert_compile Compile time assertions
35 * @ingroup grp_rt
36 *
37 * These assertions are used to check structure sizes, member/size alignments
38 * and similar compile time expressions.
39 *
40 * @remarks As you might have noticed, the AssertCompile macros don't follow the
41 * coding guidelines wrt to macros supposedly being all uppercase and
42 * underscored. For various reasons they don't, and nobody has
43 * complained yet.
44 *
45 * @{
46 */
47
48/**
49 * RTASSERTTYPE is the type the AssertCompile() macro redefines.
50 * It has no other function and shouldn't be used.
51 * Visual C++ uses this.
52 */
53typedef int RTASSERTTYPE[1];
54
55/**
56 * RTASSERTVAR is the type the AssertCompile() macro redefines.
57 * It has no other function and shouldn't be used.
58 * GCC uses this.
59 */
60#ifdef __GNUC__
61RT_C_DECLS_BEGIN
62#endif
63extern int RTASSERTVAR[1];
64#ifdef __GNUC__
65RT_C_DECLS_END
66#endif
67
68/** @def RTASSERT_HAVE_STATIC_ASSERT
69 * Indicates that the compiler implements static_assert(expr, msg).
70 */
71#ifdef _MSC_VER
72# if _MSC_VER >= 1600 && defined(__cplusplus)
73# define RTASSERT_HAVE_STATIC_ASSERT
74# endif
75#endif
76#if defined(__GNUC__) && defined(__GXX_EXPERIMENTAL_CXX0X__)
77# define RTASSERT_HAVE_STATIC_ASSERT
78#endif
79#if RT_CLANG_PREREQ(6, 0)
80# if __has_feature(cxx_static_assert) || __has_feature(c_static_assert)
81# define RTASSERT_HAVE_STATIC_ASSERT
82# endif
83#endif
84#ifdef DOXYGEN_RUNNING
85# define RTASSERT_HAVE_STATIC_ASSERT
86#endif
87
88/** @def AssertCompileNS
89 * Asserts that a compile-time expression is true. If it's not break the build.
90 *
91 * This differs from AssertCompile in that it accepts some more expressions
92 * than what C++0x allows - NS = Non-standard.
93 *
94 * @param expr Expression which should be true.
95 */
96#ifdef __GNUC__
97# define AssertCompileNS(expr) extern int RTASSERTVAR[1] __attribute__((__unused__)), RTASSERTVAR[(expr) ? 1 : 0] __attribute__((__unused__))
98#elif defined(__IBMC__) || defined(__IBMCPP__)
99# define AssertCompileNS(expr) extern int RTASSERTVAR[(expr) ? 1 : 0]
100#else
101# define AssertCompileNS(expr) typedef int RTASSERTTYPE[(expr) ? 1 : 0]
102#endif
103
104/** @def AssertCompile
105 * Asserts that a C++0x compile-time expression is true. If it's not break the
106 * build.
107 * @param expr Expression which should be true.
108 */
109#ifdef RTASSERT_HAVE_STATIC_ASSERT
110# define AssertCompile(expr) static_assert(!!(expr), #expr)
111#else
112# define AssertCompile(expr) AssertCompileNS(expr)
113#endif
114
115/** @def RTASSERT_OFFSET_OF()
116 * A offsetof() macro suitable for compile time assertions.
117 * Both GCC v4 and VisualAge for C++ v3.08 has trouble using RT_OFFSETOF.
118 */
119#if defined(__GNUC__)
120# if __GNUC__ >= 4
121# define RTASSERT_OFFSET_OF(a_Type, a_Member) __builtin_offsetof(a_Type, a_Member)
122# else
123# define RTASSERT_OFFSET_OF(a_Type, a_Member) RT_OFFSETOF(a_Type, a_Member)
124# endif
125#elif (defined(__IBMC__) || defined(__IBMCPP__)) && defined(RT_OS_OS2)
126# define RTASSERT_OFFSET_OF(a_Type, a_Member) __offsetof(a_Type, a_Member)
127#elif (defined(__WATCOMC__) && defined(__cplusplus))
128# define RTASSERT_OFFSET_OF(a_Type, a_Member) __offsetof(a_Type, a_Member)
129#else
130# define RTASSERT_OFFSET_OF(a_Type, a_Member) RT_OFFSETOF(a_Type, a_Member)
131#endif
132
133
134/** @def AssertCompileSize
135 * Asserts a size at compile.
136 * @param type The type.
137 * @param size The expected type size.
138 */
139#define AssertCompileSize(type, size) \
140 AssertCompile(sizeof(type) == (size))
141
142/** @def AssertCompileSizeAlignment
143 * Asserts a size alignment at compile.
144 * @param type The type.
145 * @param align The size alignment to assert.
146 */
147#define AssertCompileSizeAlignment(type, align) \
148 AssertCompile(!(sizeof(type) & ((align) - 1)))
149
150/** @def AssertCompileMemberSize
151 * Asserts a member offset alignment at compile.
152 * @param type The type.
153 * @param member The member.
154 * @param size The member size to assert.
155 */
156#define AssertCompileMemberSize(type, member, size) \
157 AssertCompile(RT_SIZEOFMEMB(type, member) == (size))
158
159/** @def AssertCompileMemberSizeAlignment
160 * Asserts a member size alignment at compile.
161 * @param type The type.
162 * @param member The member.
163 * @param align The member size alignment to assert.
164 */
165#define AssertCompileMemberSizeAlignment(type, member, align) \
166 AssertCompile(!(RT_SIZEOFMEMB(type, member) & ((align) - 1)))
167
168/** @def AssertCompileMemberAlignment
169 * Asserts a member offset alignment at compile.
170 * @param type The type.
171 * @param member The member.
172 * @param align The member offset alignment to assert.
173 */
174#define AssertCompileMemberAlignment(type, member, align) \
175 AssertCompile(!(RTASSERT_OFFSET_OF(type, member) & ((align) - 1)))
176
177/** @def AssertCompileMemberOffset
178 * Asserts an offset of a structure member at compile.
179 * @param type The type.
180 * @param member The member.
181 * @param off The expected offset.
182 */
183#define AssertCompileMemberOffset(type, member, off) \
184 AssertCompile(RTASSERT_OFFSET_OF(type, member) == (off))
185
186/** @def AssertCompile2MemberOffsets
187 * Asserts that two (sub-structure) members in union have the same offset.
188 * @param type The type.
189 * @param member1 The first member.
190 * @param member2 The second member.
191 */
192#define AssertCompile2MemberOffsets(type, member1, member2) \
193 AssertCompile(RTASSERT_OFFSET_OF(type, member1) == RTASSERT_OFFSET_OF(type, member2))
194
195/** @def AssertCompileAdjacentMembers
196 * Asserts that two structure members are adjacent.
197 * @param type The type.
198 * @param member1 The first member.
199 * @param member2 The second member.
200 */
201#define AssertCompileAdjacentMembers(type, member1, member2) \
202 AssertCompile(RTASSERT_OFFSET_OF(type, member1) + RT_SIZEOFMEMB(type, member1) == RTASSERT_OFFSET_OF(type, member2))
203
204/** @def AssertCompileMembersAtSameOffset
205 * Asserts that members of two different structures are at the same offset.
206 * @param type1 The first type.
207 * @param member1 The first member.
208 * @param type2 The second type.
209 * @param member2 The second member.
210 */
211#define AssertCompileMembersAtSameOffset(type1, member1, type2, member2) \
212 AssertCompile(RTASSERT_OFFSET_OF(type1, member1) == RTASSERT_OFFSET_OF(type2, member2))
213
214/** @def AssertCompileMembersSameSize
215 * Asserts that members of two different structures have the same size.
216 * @param type1 The first type.
217 * @param member1 The first member.
218 * @param type2 The second type.
219 * @param member2 The second member.
220 */
221#define AssertCompileMembersSameSize(type1, member1, type2, member2) \
222 AssertCompile(RT_SIZEOFMEMB(type1, member1) == RT_SIZEOFMEMB(type2, member2))
223
224/** @def AssertCompileMembersSameSizeAndOffset
225 * Asserts that members of two different structures have the same size and are
226 * at the same offset.
227 * @param type1 The first type.
228 * @param member1 The first member.
229 * @param type2 The second type.
230 * @param member2 The second member.
231 */
232#define AssertCompileMembersSameSizeAndOffset(type1, member1, type2, member2) \
233 AssertCompile( RTASSERT_OFFSET_OF(type1, member1) == RTASSERT_OFFSET_OF(type2, member2) \
234 && RT_SIZEOFMEMB(type1, member1) == RT_SIZEOFMEMB(type2, member2))
235
236/** @} */
237
238#endif
239
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette