blob: 6d4249c8fba85ae0a997408b5c8f8b96c8c5d3f5 [file] [log] [blame]
henrike@webrtc.org47be73b2014-05-13 18:00:26 +00001/*
2 * Copyright 2013 The WebRTC Project Authors. All rights reserved.
3 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
11// COMPILE_ASSERT macro, borrowed from google3/base/macros.h.
12#ifndef WEBRTC_BASE_COMPILE_ASSERT_H_
13#define WEBRTC_BASE_COMPILE_ASSERT_H_
14
15// The COMPILE_ASSERT macro can be used to verify that a compile time
16// expression is true. For example, you could use it to verify the
17// size of a static array:
18//
19// COMPILE_ASSERT(ARRAYSIZE(content_type_names) == CONTENT_NUM_TYPES,
20// content_type_names_incorrect_size);
21//
22// or to make sure a struct is smaller than a certain size:
23//
24// COMPILE_ASSERT(sizeof(foo) < 128, foo_too_large);
25//
26// The second argument to the macro is the name of the variable. If
27// the expression is false, most compilers will issue a warning/error
28// containing the name of the variable.
29
30// TODO(ajm): Hack to avoid multiple definitions until the base/ of webrtc and
31// libjingle are merged.
32#if !defined(COMPILE_ASSERT)
33template <bool>
34struct CompileAssert {
35};
36
37#define COMPILE_ASSERT(expr, msg) \
38 typedef CompileAssert<(bool(expr))> msg[bool(expr) ? 1 : -1] // NOLINT
39#endif // COMPILE_ASSERT
40
41// Implementation details of COMPILE_ASSERT:
42//
43// - COMPILE_ASSERT works by defining an array type that has -1
44// elements (and thus is invalid) when the expression is false.
45//
46// - The simpler definition
47//
48// #define COMPILE_ASSERT(expr, msg) typedef char msg[(expr) ? 1 : -1]
49//
50// does not work, as gcc supports variable-length arrays whose sizes
51// are determined at run-time (this is gcc's extension and not part
52// of the C++ standard). As a result, gcc fails to reject the
53// following code with the simple definition:
54//
55// int foo;
56// COMPILE_ASSERT(foo, msg); // not supposed to compile as foo is
57// // not a compile-time constant.
58//
59// - By using the type CompileAssert<(bool(expr))>, we ensures that
60// expr is a compile-time constant. (Template arguments must be
61// determined at compile-time.)
62//
63// - The outer parentheses in CompileAssert<(bool(expr))> are necessary
64// to work around a bug in gcc 3.4.4 and 4.0.1. If we had written
65//
66// CompileAssert<bool(expr)>
67//
68// instead, these compilers will refuse to compile
69//
70// COMPILE_ASSERT(5 > 0, some_message);
71//
72// (They seem to think the ">" in "5 > 0" marks the end of the
73// template argument list.)
74//
75// - The array size is (bool(expr) ? 1 : -1), instead of simply
76//
77// ((expr) ? 1 : -1).
78//
79// This is to avoid running into a bug in MS VC 7.1, which
80// causes ((0.0) ? 1 : -1) to incorrectly evaluate to 1.
81
82#endif // WEBRTC_BASE_COMPILE_ASSERT_H_