base: Check for static_assert support and provide fallback

C++11 has support for static_asserts to provide compile-time assertion
checking. This is very useful when testing, for example, structure
sizes to make sure that the compiler got the right alignment or vector
sizes.
This commit is contained in:
Andreas Sandberg 2012-09-25 11:49:40 -05:00
parent 6598241f2c
commit 4544f3def4
2 changed files with 49 additions and 2 deletions

View file

@ -684,17 +684,34 @@ def CheckLeading(context):
context.Result(ret)
return ret
# Test for the presence of C++11 static asserts. If the compiler lacks
# support for static asserts, base/compiler.hh enables a macro that
# removes any static asserts in the code.
def CheckStaticAssert(context):
context.Message("Checking for C++11 static_assert support...")
ret = context.TryCompile('''
static_assert(1, "This assert is always true");
''', extension=".cc")
context.env.Append(HAVE_STATIC_ASSERT=ret)
context.Result(ret)
return ret
# Platform-specific configuration. Note again that we assume that all
# builds under a given build root run on the same host platform.
conf = Configure(main,
conf_dir = joinpath(build_root, '.scons_config'),
log_file = joinpath(build_root, 'scons_config.log'),
custom_tests = { 'CheckLeading' : CheckLeading })
custom_tests = { 'CheckLeading' : CheckLeading,
'CheckStaticAssert' : CheckStaticAssert,
})
# Check for leading underscores. Don't really need to worry either
# way so don't need to check the return code.
conf.CheckLeading()
# Check for C++11 features we want to use if they exist
conf.CheckStaticAssert()
# Check if we should compile a 64 bit binary on Mac OS X/Darwin
try:
import platform
@ -923,7 +940,7 @@ sticky_vars.AddVariables(
# These variables get exported to #defines in config/*.hh (see src/SConscript).
export_vars += ['USE_FENV', 'SS_COMPATIBLE_FP',
'TARGET_ISA', 'CP_ANNOTATE', 'USE_POSIX_CLOCK', 'PROTOCOL',
]
'HAVE_STATIC_ASSERT']
###################################################
#

View file

@ -31,6 +31,8 @@
#ifndef __BASE_COMPILER_HH__
#define __BASE_COMPILER_HH__
#include "config/have_static_assert.hh"
//http://msdn2.microsoft.com/en-us/library/ms937669.aspx
//http://msdn2.microsoft.com/en-us/library/aa448724.aspx
//http://docs.sun.com/source/819-3688/sun.specific.html#marker-998278
@ -56,4 +58,32 @@
#error "Need to define compiler options in base/compiler.hh"
#endif
/*
* Define a compatibility macro that emulates the behavior of
* static_assert using template magic if the compiler doesn't have
* native support.
*/
#if !HAVE_STATIC_ASSERT
template<bool>
struct static_assert_failure;
template<>
struct static_assert_failure<false> {};
/* The following macro causes the compiler to evaluate the size of the
* static_assert_failure struct. The templates are designed so that
* only static_assert_failure<false> evaluates to a proper size, while
* static_assert_failure<true> generates a compile time error.
*/
#define static_assert(expr, msg) \
namespace ns_static_assert { \
enum { \
static_assert_ ## __LINE__ = \
sizeof(static_assert_failure<!(expr)>) \
}; \
}
#endif
#endif // __BASE_COMPILER_HH__