Opened 7 years ago

Closed 4 years ago

#11514 closed Bugs (fixed)

Thread-unsafe (or non-optimal in C++11) static initialization in boost/spirit/home/qi/numeric/detail/numeric_utils.hpp

Reported by: Artem Tokmakov <artyom.tokmakov@…> Owned by: Joel de Guzman
Milestone: To Be Determined Component: spirit
Version: Boost 1.58.0 Severity: Problem
Keywords: unsafe initialization Cc:

Description

This file (it's the same in boost 1.58 which I have too): boost/spirit/home/qi/numeric/detail/numeric_utils.hpp has following code (similar in a couple of places):

// Ensure n *= Radix will not overflow
static T const max = (std::numeric_limits<T>::max)();
static T const val = max / Radix;

Since static initialization is not thread-safe in Visual Studio (the one I'm using now is 2013 update 4), and because these variables are dependent on each other, this causes problems. Indeed, sometimes I get val initialized to 0, and other times to correct value.

But even when "magic statics" are implemented, this will probably be not the most efficient implementation since a better one would be using, say, constexpr.

There are couple of ways to fix this, and one with minimal changes (considering my minimal knowledge of boost constexpr machinery) would be:

// ## Note how two variables are initialized independently.
static T const max = (std::numeric_limits<T>::max)();
static T const val = (std::numeric_limits<T>::max)() / Radix;

Thanks!

Change History (3)

comment:1 by Joel de Guzman, 7 years ago

Makes sense. Could you please provide a pull request here: https://github.com/boostorg/spirit/tree/develop

comment:3 by Joel de Guzman, 4 years ago

Resolution: fixed
Status: newclosed
Note: See TracTickets for help on using tickets.