VirtualBox

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

Last change on this file was 103001, checked in by vboxsync, 4 months ago

iprt/assertcompile.h,iprt/stdint.h: Made these header usable with the assemlber on darwin/arm64. bugref:10376

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 9.7 KB
RevLine 
[1]1/** @file
[68686]2 * IPRT - Compile Time Assertions.
[1]3 */
4
5/*
[98103]6 * Copyright (C) 2006-2023 Oracle and/or its affiliates.
[1]7 *
[96407]8 * This file is part of VirtualBox base platform packages, as
9 * available from https://www.virtualbox.org.
[5999]10 *
[96407]11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License
13 * as published by the Free Software Foundation, in version 3 of the
14 * License.
15 *
16 * This program is distributed in the hope that it will be useful, but
17 * WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, see <https://www.gnu.org/licenses>.
23 *
[5999]24 * The contents of this file may alternatively be used under the terms
25 * of the Common Development and Distribution License Version 1.0
[96407]26 * (CDDL), a copy of it is provided in the "COPYING.CDDL" file included
27 * in the VirtualBox distribution, in which case the provisions of the
[5999]28 * CDDL are applicable instead of those of the GPL.
29 *
30 * You may elect to license modified versions of this file under the
31 * terms and conditions of either the GPL or the CDDL or both.
[96407]32 *
33 * SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0
[1]34 */
35
[76557]36#ifndef IPRT_INCLUDED_assertcompile_h
37#define IPRT_INCLUDED_assertcompile_h
[76507]38#ifndef RT_WITHOUT_PRAGMA_ONCE
39# pragma once
40#endif
[1]41
42#include <iprt/cdefs.h>
43
[68686]44/** @defgroup grp_rt_assert_compile Compile time assertions
[1]45 * @ingroup grp_rt
[6814]46 *
[18575]47 * These assertions are used to check structure sizes, member/size alignments
[13306]48 * and similar compile time expressions.
49 *
[68686]50 * @remarks As you might have noticed, the AssertCompile macros don't follow the
51 * coding guidelines wrt to macros supposedly being all uppercase and
52 * underscored. For various reasons they don't, and nobody has
53 * complained yet.
54 *
[13306]55 * @{
56 */
57
[103001]58
[1]59/**
60 * RTASSERTTYPE is the type the AssertCompile() macro redefines.
61 * It has no other function and shouldn't be used.
62 * Visual C++ uses this.
63 */
[103001]64#ifndef __ASSEMBLER__
[1]65typedef int RTASSERTTYPE[1];
[103001]66#endif
[1]67
68/**
69 * RTASSERTVAR is the type the AssertCompile() macro redefines.
70 * It has no other function and shouldn't be used.
[97962]71 *
[97969]72 * GCC and IBM VisualAge C/C++ uses this. GCC doesn't technicaly need this
73 * global scope one as it declares it for each use, however things get
74 * complicated in C++ code where most GCC and clang versions gets upset by mixed
75 * "C" and "C++" versions of the symbol when using inside and outside
76 * RT_C_DECLS_BEGIN/END. The GCC 3.3.x and 3.4.x versions we use, OTOH will
77 * always complain about unused RTASSERTVAR for each AssertCompileNS use in a
78 * function if we declare it globally, so we don't do it for those, but we do
79 * for 4.x+ to prevent linkage confusion.
[1]80 */
[103001]81#ifndef __ASSEMBLER__
82# if !defined(__cplusplus) || !defined(__GNUC__)
[1]83extern int RTASSERTVAR[1];
[103001]84# elif RT_GNUC_PREREQ(4, 0) || defined(__clang_major__) /* Not sure when they fixed the global scoping __unused__/whatever problem. */
[97969]85RT_C_DECLS_BEGIN
86extern int RTASSERTVAR[1];
87RT_C_DECLS_END
[103001]88# endif
[1208]89#endif
[1]90
[30240]91/** @def RTASSERT_HAVE_STATIC_ASSERT
92 * Indicates that the compiler implements static_assert(expr, msg).
93 */
[103001]94#ifndef __ASSEMBLER__
95# ifdef _MSC_VER
96# if _MSC_VER >= 1600 && defined(__cplusplus) && !defined(VBOX_WITH_PARFAIT)
[30240]97# define RTASSERT_HAVE_STATIC_ASSERT
[103001]98# endif
[30240]99# endif
[103001]100# if defined(__GNUC__) && defined(__GXX_EXPERIMENTAL_CXX0X__)
[60965]101# define RTASSERT_HAVE_STATIC_ASSERT
102# endif
[103001]103# if RT_CLANG_PREREQ(6, 0)
104# if __has_feature(cxx_static_assert) || __has_feature(c_static_assert)
105# define RTASSERT_HAVE_STATIC_ASSERT
106# endif
107# endif
[60965]108#endif
[30240]109#ifdef DOXYGEN_RUNNING
110# define RTASSERT_HAVE_STATIC_ASSERT
111#endif
112
[30253]113/** @def AssertCompileNS
[1]114 * Asserts that a compile-time expression is true. If it's not break the build.
[30253]115 *
116 * This differs from AssertCompile in that it accepts some more expressions
117 * than what C++0x allows - NS = Non-standard.
118 *
[1]119 * @param expr Expression which should be true.
120 */
[103001]121#ifdef __ASSEMBLER__
122# define AssertCompileNS(expr)
123#elif defined(__GNUC__)
[97969]124# define AssertCompileNS(expr) AssertCompileNS2(expr,RTASSERTVAR)
125# define AssertCompileNS2(expr,a_VarName) extern int a_VarName[ 1 ] __attribute__((__unused__)), \
[97966]126 a_VarName[(expr) ? 1 : 0] __attribute__((__unused__))
[46689]127#elif defined(__IBMC__) || defined(__IBMCPP__)
128# define AssertCompileNS(expr) extern int RTASSERTVAR[(expr) ? 1 : 0]
[30253]129#else
130# define AssertCompileNS(expr) typedef int RTASSERTTYPE[(expr) ? 1 : 0]
131#endif
132
133/** @def AssertCompile
134 * Asserts that a C++0x compile-time expression is true. If it's not break the
135 * build.
136 * @param expr Expression which should be true.
137 */
[30240]138#ifdef RTASSERT_HAVE_STATIC_ASSERT
[77109]139# ifdef __cplusplus
140# define AssertCompile(expr) static_assert(!!(expr), #expr)
141# else
142# define AssertCompile(expr) _Static_assert(!!(expr), #expr)
143# endif
[1]144#else
[30253]145# define AssertCompile(expr) AssertCompileNS(expr)
[1]146#endif
147
[46689]148/** @def RTASSERT_OFFSET_OF()
[48934]149 * A offsetof() macro suitable for compile time assertions.
[46689]150 * Both GCC v4 and VisualAge for C++ v3.08 has trouble using RT_OFFSETOF.
151 */
152#if defined(__GNUC__)
153# if __GNUC__ >= 4
154# define RTASSERT_OFFSET_OF(a_Type, a_Member) __builtin_offsetof(a_Type, a_Member)
155# else
156# define RTASSERT_OFFSET_OF(a_Type, a_Member) RT_OFFSETOF(a_Type, a_Member)
157# endif
158#elif (defined(__IBMC__) || defined(__IBMCPP__)) && defined(RT_OS_OS2)
159# define RTASSERT_OFFSET_OF(a_Type, a_Member) __offsetof(a_Type, a_Member)
[68615]160#elif (defined(__WATCOMC__) && defined(__cplusplus))
161# define RTASSERT_OFFSET_OF(a_Type, a_Member) __offsetof(a_Type, a_Member)
[46689]162#else
163# define RTASSERT_OFFSET_OF(a_Type, a_Member) RT_OFFSETOF(a_Type, a_Member)
164#endif
165
166
[1]167/** @def AssertCompileSize
168 * Asserts a size at compile.
169 * @param type The type.
170 * @param size The expected type size.
171 */
172#define AssertCompileSize(type, size) \
173 AssertCompile(sizeof(type) == (size))
174
175/** @def AssertCompileSizeAlignment
176 * Asserts a size alignment at compile.
177 * @param type The type.
178 * @param align The size alignment to assert.
179 */
180#define AssertCompileSizeAlignment(type, align) \
181 AssertCompile(!(sizeof(type) & ((align) - 1)))
182
[9367]183/** @def AssertCompileMemberSize
184 * Asserts a member offset alignment at compile.
185 * @param type The type.
186 * @param member The member.
187 * @param size The member size to assert.
188 */
189#define AssertCompileMemberSize(type, member, size) \
190 AssertCompile(RT_SIZEOFMEMB(type, member) == (size))
191
192/** @def AssertCompileMemberSizeAlignment
193 * Asserts a member size alignment at compile.
194 * @param type The type.
195 * @param member The member.
196 * @param align The member size alignment to assert.
197 */
198#define AssertCompileMemberSizeAlignment(type, member, align) \
199 AssertCompile(!(RT_SIZEOFMEMB(type, member) & ((align) - 1)))
200
[1]201/** @def AssertCompileMemberAlignment
202 * Asserts a member offset alignment at compile.
203 * @param type The type.
204 * @param member The member.
205 * @param align The member offset alignment to assert.
206 */
[46689]207#define AssertCompileMemberAlignment(type, member, align) \
208 AssertCompile(!(RTASSERT_OFFSET_OF(type, member) & ((align) - 1)))
[1]209
[9367]210/** @def AssertCompileMemberOffset
[36573]211 * Asserts an offset of a structure member at compile.
[1]212 * @param type The type.
213 * @param member The member.
[9367]214 * @param off The expected offset.
[1]215 */
[46689]216#define AssertCompileMemberOffset(type, member, off) \
217 AssertCompile(RTASSERT_OFFSET_OF(type, member) == (off))
[1]218
[21792]219/** @def AssertCompile2MemberOffsets
220 * Asserts that two (sub-structure) members in union have the same offset.
221 * @param type The type.
222 * @param member1 The first member.
223 * @param member2 The second member.
224 */
[46689]225#define AssertCompile2MemberOffsets(type, member1, member2) \
226 AssertCompile(RTASSERT_OFFSET_OF(type, member1) == RTASSERT_OFFSET_OF(type, member2))
[21792]227
[28619]228/** @def AssertCompileAdjacentMembers
229 * Asserts that two structure members are adjacent.
230 * @param type The type.
231 * @param member1 The first member.
232 * @param member2 The second member.
233 */
[46689]234#define AssertCompileAdjacentMembers(type, member1, member2) \
235 AssertCompile(RTASSERT_OFFSET_OF(type, member1) + RT_SIZEOFMEMB(type, member1) == RTASSERT_OFFSET_OF(type, member2))
[28619]236
[30240]237/** @def AssertCompileMembersAtSameOffset
238 * Asserts that members of two different structures are at the same offset.
239 * @param type1 The first type.
240 * @param member1 The first member.
241 * @param type2 The second type.
242 * @param member2 The second member.
243 */
[46689]244#define AssertCompileMembersAtSameOffset(type1, member1, type2, member2) \
245 AssertCompile(RTASSERT_OFFSET_OF(type1, member1) == RTASSERT_OFFSET_OF(type2, member2))
[48934]246
[30240]247/** @def AssertCompileMembersSameSize
248 * Asserts that members of two different structures have the same size.
249 * @param type1 The first type.
250 * @param member1 The first member.
251 * @param type2 The second type.
252 * @param member2 The second member.
253 */
254#define AssertCompileMembersSameSize(type1, member1, type2, member2) \
255 AssertCompile(RT_SIZEOFMEMB(type1, member1) == RT_SIZEOFMEMB(type2, member2))
256
257/** @def AssertCompileMembersSameSizeAndOffset
258 * Asserts that members of two different structures have the same size and are
259 * at the same offset.
260 * @param type1 The first type.
261 * @param member1 The first member.
262 * @param type2 The second type.
263 * @param member2 The second member.
264 */
[46689]265#define AssertCompileMembersSameSizeAndOffset(type1, member1, type2, member2) \
266 AssertCompile( RTASSERT_OFFSET_OF(type1, member1) == RTASSERT_OFFSET_OF(type2, member2) \
267 && RT_SIZEOFMEMB(type1, member1) == RT_SIZEOFMEMB(type2, member2))
[30240]268
[13306]269/** @} */
[1]270
[76585]271#endif /* !IPRT_INCLUDED_assertcompile_h */
[25548]272
Note: See TracBrowser for help on using the repository browser.

© 2023 Oracle
ContactPrivacy policyTerms of Use