VirtualBox

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

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

assertcompile.h: Use _Static_assert() when compiling in C mode and static asserts are available, static_assert() is C++11 only while _Static_assert() is for C11. (clang compile fix)

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 8.3 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_INCLUDED_assertcompile_h
27#define IPRT_INCLUDED_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# ifdef __cplusplus
111# define AssertCompile(expr) static_assert(!!(expr), #expr)
112# else
113# define AssertCompile(expr) _Static_assert(!!(expr), #expr)
114# endif
115#else
116# define AssertCompile(expr) AssertCompileNS(expr)
117#endif
118
119/** @def RTASSERT_OFFSET_OF()
120 * A offsetof() macro suitable for compile time assertions.
121 * Both GCC v4 and VisualAge for C++ v3.08 has trouble using RT_OFFSETOF.
122 */
123#if defined(__GNUC__)
124# if __GNUC__ >= 4
125# define RTASSERT_OFFSET_OF(a_Type, a_Member) __builtin_offsetof(a_Type, a_Member)
126# else
127# define RTASSERT_OFFSET_OF(a_Type, a_Member) RT_OFFSETOF(a_Type, a_Member)
128# endif
129#elif (defined(__IBMC__) || defined(__IBMCPP__)) && defined(RT_OS_OS2)
130# define RTASSERT_OFFSET_OF(a_Type, a_Member) __offsetof(a_Type, a_Member)
131#elif (defined(__WATCOMC__) && defined(__cplusplus))
132# define RTASSERT_OFFSET_OF(a_Type, a_Member) __offsetof(a_Type, a_Member)
133#else
134# define RTASSERT_OFFSET_OF(a_Type, a_Member) RT_OFFSETOF(a_Type, a_Member)
135#endif
136
137
138/** @def AssertCompileSize
139 * Asserts a size at compile.
140 * @param type The type.
141 * @param size The expected type size.
142 */
143#define AssertCompileSize(type, size) \
144 AssertCompile(sizeof(type) == (size))
145
146/** @def AssertCompileSizeAlignment
147 * Asserts a size alignment at compile.
148 * @param type The type.
149 * @param align The size alignment to assert.
150 */
151#define AssertCompileSizeAlignment(type, align) \
152 AssertCompile(!(sizeof(type) & ((align) - 1)))
153
154/** @def AssertCompileMemberSize
155 * Asserts a member offset alignment at compile.
156 * @param type The type.
157 * @param member The member.
158 * @param size The member size to assert.
159 */
160#define AssertCompileMemberSize(type, member, size) \
161 AssertCompile(RT_SIZEOFMEMB(type, member) == (size))
162
163/** @def AssertCompileMemberSizeAlignment
164 * Asserts a member size alignment at compile.
165 * @param type The type.
166 * @param member The member.
167 * @param align The member size alignment to assert.
168 */
169#define AssertCompileMemberSizeAlignment(type, member, align) \
170 AssertCompile(!(RT_SIZEOFMEMB(type, member) & ((align) - 1)))
171
172/** @def AssertCompileMemberAlignment
173 * Asserts a member offset alignment at compile.
174 * @param type The type.
175 * @param member The member.
176 * @param align The member offset alignment to assert.
177 */
178#define AssertCompileMemberAlignment(type, member, align) \
179 AssertCompile(!(RTASSERT_OFFSET_OF(type, member) & ((align) - 1)))
180
181/** @def AssertCompileMemberOffset
182 * Asserts an offset of a structure member at compile.
183 * @param type The type.
184 * @param member The member.
185 * @param off The expected offset.
186 */
187#define AssertCompileMemberOffset(type, member, off) \
188 AssertCompile(RTASSERT_OFFSET_OF(type, member) == (off))
189
190/** @def AssertCompile2MemberOffsets
191 * Asserts that two (sub-structure) members in union have the same offset.
192 * @param type The type.
193 * @param member1 The first member.
194 * @param member2 The second member.
195 */
196#define AssertCompile2MemberOffsets(type, member1, member2) \
197 AssertCompile(RTASSERT_OFFSET_OF(type, member1) == RTASSERT_OFFSET_OF(type, member2))
198
199/** @def AssertCompileAdjacentMembers
200 * Asserts that two structure members are adjacent.
201 * @param type The type.
202 * @param member1 The first member.
203 * @param member2 The second member.
204 */
205#define AssertCompileAdjacentMembers(type, member1, member2) \
206 AssertCompile(RTASSERT_OFFSET_OF(type, member1) + RT_SIZEOFMEMB(type, member1) == RTASSERT_OFFSET_OF(type, member2))
207
208/** @def AssertCompileMembersAtSameOffset
209 * Asserts that members of two different structures are at the same offset.
210 * @param type1 The first type.
211 * @param member1 The first member.
212 * @param type2 The second type.
213 * @param member2 The second member.
214 */
215#define AssertCompileMembersAtSameOffset(type1, member1, type2, member2) \
216 AssertCompile(RTASSERT_OFFSET_OF(type1, member1) == RTASSERT_OFFSET_OF(type2, member2))
217
218/** @def AssertCompileMembersSameSize
219 * Asserts that members of two different structures have the same size.
220 * @param type1 The first type.
221 * @param member1 The first member.
222 * @param type2 The second type.
223 * @param member2 The second member.
224 */
225#define AssertCompileMembersSameSize(type1, member1, type2, member2) \
226 AssertCompile(RT_SIZEOFMEMB(type1, member1) == RT_SIZEOFMEMB(type2, member2))
227
228/** @def AssertCompileMembersSameSizeAndOffset
229 * Asserts that members of two different structures have the same size and are
230 * at the same offset.
231 * @param type1 The first type.
232 * @param member1 The first member.
233 * @param type2 The second type.
234 * @param member2 The second member.
235 */
236#define AssertCompileMembersSameSizeAndOffset(type1, member1, type2, member2) \
237 AssertCompile( RTASSERT_OFFSET_OF(type1, member1) == RTASSERT_OFFSET_OF(type2, member2) \
238 && RT_SIZEOFMEMB(type1, member1) == RT_SIZEOFMEMB(type2, member2))
239
240/** @} */
241
242#endif /* !IPRT_INCLUDED_assertcompile_h */
243
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle
ContactPrivacy/Do Not Sell My InfoTerms of Use