C++ namesapces: <cmath> is std:: <cmath>, <math.h> is ::

175 views
Skip to first unread message

Bob Carpenter

unread,
Jun 6, 2015, 2:43:46 PM6/6/15
to stan...@googlegroups.com
There's a question down below.

I'm trying to remove all the uses of <math.h> in Stan because
it brings in functions in namespace ::, which pollutes all
other namespaces.

Alas, many functions (exp2, expm1, log1, log1p, etc.) are *not*
defined in <cmath> until C++11, but only exist in the C99-derived
<math.h>. See:

http://www.cplusplus.com/reference/cmath/

Everything works on the Mac clang++ side because they declare
those C++11 functions in <cmath> with the std:: namespace. But
it doesn't work on Windows, which only defines them where the
spec says you'll find them, in <math.h>.

These functions are all defined by Boost in the Boost namespace.

I'm still trying to fight through getting max() to work in
size declarations and constraints for variables.

I'd like to remove <math.h>, but I'm worried about name conflicts
if I bring in the Boost versions with a using in the model (the way
we currently hack in lgamma).

QUESTION: What should we do?

A1: Follow lgamma and add a using statement for the Boost versions
to the generated Stan program code for each of these functions and
an include and using statement in the associated calls in rev and fwd
autodiff.

A2: Define these problematic functions in stan::math as facades around
the Boost implementations so they get brought in with "using stan::math"
in the generated program code.

A3: Define *all* of our functions in stan::math and fully qualify all
the calls in the generated code. Rather than argument-dependent lookup,
all Stan function calls would be overloading of the same function in the
same namespace. The user-defined functions would be qualified separately.

A4: <your answer here>

With A1 or A2, when C++11 hits, we just get rid of the using statements (A1) or
definitions (A2).

I'm leaning toward A1 because it's less work. It also forces us to
play nicely with everyone's namespaces.

What I worry about either way is that client code with "using namespace std" or
"include <math.h>" will make double-based versions of these calls ambiguous.

- Bob



Bob Carpenter

unread,
Jun 6, 2015, 3:02:45 PM6/6/15
to stan...@googlegroups.com
Note: Boost by default configures these functions to throw exceptions,
whereas the <math.h> versions just silently return NaN. I think
the exceptions are a good thing --- throw a warning at the earliest
sign of arithmetic trouble.

- Bob
> --
> You received this message because you are subscribed to the Google Groups "stan development mailing list" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to stan-dev+u...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.
>

Ben Goodrich

unread,
Jun 6, 2015, 3:13:18 PM6/6/15
to stan...@googlegroups.com, ca...@alias-i.com
On Saturday, June 6, 2015 at 2:43:46 PM UTC-4, Bob Carpenter wrote:
I'm leaning toward A1 because it's less work.  It also forces us to
play nicely with everyone's namespaces.  

I think the path of least resistence makes sense. According to CRAN "A change to a new [C++11 supporting] toolchain is expected during the R 3.2.x lifetime", although it looks as if x > 1.

Ben

Reply all
Reply to author
Forward
0 new messages