Repository: sympy/sympy

Issue:
ccode to output expm1, log1p, exp2, log2
Since C99, and C++11 respectively, there is support for:
- [expm1](http://en.cppreference.com/w/c/numeric/math/expm1)
- [log1p](http://en.cppreference.com/w/c/numeric/math/log1p)
- [exp2](http://en.cppreference.com/w/c/numeric/math/exp2)
- [log2](http://en.cppreference.com/w/c/numeric/math/log2)

These offer better precision/performance. Hence it would be nice if we could teach `ccode` how to output these, perhaps enabled using a flag not to break backward-compatibility?


Discussion:

Patch:
diff --git a/.gitignore b/.gitignore
index 0f8a7d6857..29e5182542 100644
--- a/.gitignore
+++ b/.gitignore
@@ -69,3 +69,5 @@ sample.tex
 # IPython Notebook Checkpoints
 .ipynb_checkpoints/
 
+# pytest cache folder
+.cache
diff --git a/doc/src/modules/codegen.rst b/doc/src/modules/codegen.rst
index 2c322f5902..d5070c8df9 100644
--- a/doc/src/modules/codegen.rst
+++ b/doc/src/modules/codegen.rst
@@ -93,11 +93,18 @@ Here is a simple example of printing a C version of a SymPy expression::
     -Z⋅e ⋅k
     ────────
       2⋅r
-    >>> ccode(expr)
+    >>> ccode(expr, standard='C99')
     -1.0L/2.0L*Z*pow(e, 2)*k/r
-    >>> ccode(expr, assign_to="E")
+    >>> ccode(expr, assign_to="E", standard='C99')
     E = -1.0L/2.0L*Z*pow(e, 2)*k/r;
 
+To generate code with some math functions provided by e.g. the C99 standard we need
+to import functions from :mod:`sympy.codegen.cfunctions`::
+
+    >>> from sympy.codegen.cfunctions import expm1
+    >>> ccode(expm1(x), standard='C99')
+    expm1(x)
+
 ``Piecewise`` expressions are converted into conditionals. If an ``assign_to``
 variable is provided an if statement is created, otherwise the ternary operator
 is used. Note that if the ``Piecewise`` lacks a default term, represented by
@@ -186,7 +193,7 @@ how it works::
                  r
     >>> print(jscode(expr, assign_to="H_is"))
     H_is = I*S*gamma_1*gamma_2*k*(3*Math.pow(Math.cos(beta), 2) - 1)/Math.pow(r, 3);
-    >>> print(ccode(expr, assign_to="H_is"))
+    >>> print(ccode(expr, assign_to="H_is", standard='C89'))
     H_is = I*S*gamma_1*gamma_2*k*(3*pow(cos(beta), 2) - 1)/pow(r, 3);
     >>> print(fcode(expr, assign_to="H_is"))
           H_is = I*S*gamma_1*gamma_2*k*(3*cos(beta)**2 - 1)/r**3
@@ -219,7 +226,7 @@ For instance::
     >>> from sympy.utilities.codegen import codegen
     >>> length, breadth, height = symbols('length, breadth, height')
     >>> [(c_name, c_code), (h_name, c_header)] = \
-    ... codegen(('volume', length*breadth*height), "C", "test",
+    ... codegen(('volume', length*breadth*height), "C99", "test",
     ...         header=False, empty=False)
     >>> print(c_name)
     test.c
@@ -543,3 +550,9 @@ available with ``autowrap``.
 
 There are other facilities available with Sympy to do efficient numeric
 computation. See :ref:`this<numeric_computation>` page for a comparison among them.
+
+Special (finite precision arithmetic) math functions
+----------------------------------------------------
+
+.. automodule:: sympy.codegen.cfunctions
+    :members:
diff --git a/doc/src/modules/printing.rst b/doc/src/modules/printing.rst
index ccce7d0340..97afad54fc 100644
--- a/doc/src/modules/printing.rst
+++ b/doc/src/modules/printing.rst
@@ -49,38 +49,78 @@ when possible.
 .. autofunction:: pretty
 .. autofunction:: pretty_print
 
-CCodePrinter
-------------
+C code printers
+---------------
 
 .. module:: sympy.printing.ccode
 
-This class implements C code printing (i.e. it converts Python expressions
-to strings of C code).
+This class implements C code printing, i.e. it converts Python expressions
+to strings of C code (see also ``C89CodePrinter``).
 
 Usage::
 
     >>> from sympy.printing import print_ccode
-    >>> from sympy.functions import sin, cos, Abs
+    >>> from sympy.functions import sin, cos, Abs, gamma
     >>> from sympy.abc import x
-    >>> print_ccode(sin(x)**2 + cos(x)**2)
+    >>> print_ccode(sin(x)**2 + cos(x)**2, standard='C89')
     pow(sin(x), 2) + pow(cos(x), 2)
-    >>> print_ccode(2*x + cos(x), assign_to="result")
+    >>> print_ccode(2*x + cos(x), assign_to="result", standard='C89')
     result = 2*x + cos(x);
-    >>> print_ccode(Abs(x**2))
+    >>> print_ccode(Abs(x**2), standard='C89')
     fabs(pow(x, 2))
+    >>> print_ccode(gamma(x**2), standard='C99')
+    tgamma(pow(x, 2))
+
+.. autodata:: sympy.printing.ccode.known_functions_C89
+.. autodata:: sympy.printing.ccode.known_functions_C99
 
-.. autodata:: sympy.printing.ccode.known_functions
+.. autoclass:: sympy.printing.ccode.C89CodePrinter
+   :members:
+
+   .. autoattribute:: C89CodePrinter.printmethod
 
-.. autoclass:: sympy.printing.ccode.CCodePrinter
+.. autoclass:: sympy.printing.ccode.C99CodePrinter
    :members:
 
-   .. autoattribute:: CCodePrinter.printmethod
+   .. autoattribute:: C99CodePrinter.printmethod
 
 
 .. autofunction:: sympy.printing.ccode.ccode
 
 .. autofunction:: sympy.printing.ccode.print_ccode
 
+C++ code printers
+-----------------
+
+.. module:: sympy.printing.cxxcode
+
+This module contains printers for C++ code, i.e. functions to convert
+SymPy expressions to strings of C++ code.
+
+Usage::
+
+    >>> from sympy.printing.cxxcode import cxxcode
+    >>> from sympy.functions import Min, gamma
+    >>> from sympy.abc import x
+    >>> print(cxxcode(Min(gamma(x) - 1, x), standard='C++11'))
+    std::min(x, std::tgamma(x) - 1)
+
+.. autoclass:: sympy.printing.cxxcode.CXX98CodePrinter
+   :members:
+
+   .. autoattribute:: CXX98CodePrinter.printmethod
+
+
+.. autoclass:: sympy.printing.cxxcode.CXX11CodePrinter
+   :members:
+
+   .. autoattribute:: CXX11CodePrinter.printmethod
+
+
+.. autofunction:: sympy.printing.cxxcode.cxxcode
+
+
+
 RCodePrinter
 ------------
 
diff --git a/sympy/codegen/cfunctions.py b/sympy/codegen/cfunctions.py
new file mode 100644
index 0000000000..89afc7fff5
--- /dev/null
+++ b/sympy/codegen/cfunctions.py
@@ -0,0 +1,498 @@
+"""
+Functions with corresponding implementations in C.
+
+The functions defined in this module allows the user to express functions such as ``expm1``
+as a SymPy function for symbolic manipulation.
+
+"""
+
+import math
+from sympy.core.singleton import S
+from sympy.core.numbers import Rational
+from sympy.core.function import ArgumentIndexError, Function, Lambda
+from sympy.core.power import Pow
+from sympy.functions.elementary.miscellaneous import sqrt
+from sympy.functions.elementary.exponential import exp, log
+
+
+def _expm1(x):
+    return exp(x) - S.One
+
+
+class expm1(Function):
+    """
+    Represents the exponential function minus one.
+
+    The benefit of using ``expm1(x)`` over ``exp(x) - 1``
+    is that the latter is prone to cancellation under finite precision
+    arithmetic when x is close to zero.
+
+    Examples
+    ========
+    >>> from sympy.abc import x
+    >>> from sympy.codegen.cfunctions import expm1
+    >>> '%.0e' % expm1(1e-99).evalf()
+    '1e-99'
+    >>> from math import exp
+    >>> exp(1e-99) - 1
+    0.0
+    >>> expm1(x).diff(x)
+    exp(x)
+
+    See Also
+    ========
+
+    log1p
+    """
+    nargs = 1
+
+    def fdiff(self, argindex=1):
+        """
+        Returns the first derivative of this function.
+        """
+        if argindex == 1:
+            return exp(*self.args)
+        else:
+            raise ArgumentIndexError(self, argindex)
+
+    def _eval_expand_func(self, **hints):
+        return _expm1(*self.args)
+
+    def _eval_rewrite_as_exp(self, arg):
+        return exp(arg) - S.One
+
+    _eval_rewrite_as_tractable = _eval_rewrite_as_exp
+
+    @classmethod
+    def eval(cls, arg):
+        exp_arg = exp.eval(arg)
+        if exp_arg is not None:
+            return exp_arg - S.One
+
+    def _eval_is_real(self):
+        return self.args[0].is_real
+
+    def _eval_is_finite(self):
+        return self.args[0].is_finite
+
+
+
+def _log1p(x):
+    return log(x + S.One)
+
+
+class log1p(Function):
+    """
+    Represents the natural logarithm of a number plus one.
+
+    The benefit of using ``log1p(x)`` over ``log(x + 1)``
+    is that the latter is prone to cancellation under finite precision
+    arithmetic when x is close to zero.
+
+    Examples
+    ========
+    >>> from sympy.abc import x
+    >>> from sympy.codegen.cfunctions import log1p
+    >>> '%.0e' % log1p(1e-99).evalf()
+    '1e-99'
+    >>> from math import log
+    >>> log(1 + 1e-99)
+    0.0
+    >>> log1p(x).diff(x)
+    1/(x + 1)
+
+    See Also
+    ========
+
+
+    expm1
+    """
+    nargs = 1
+
+
+    def fdiff(self, argindex=1):
+        """
+        Returns the first derivative of this function.
+        """
+        if argindex == 1:
+            return S.One/(self.args[0] + S.One)
+        else:
+            raise ArgumentIndexError(self, argindex)
+
+
+    def _eval_expand_func(self, **hints):
+        return _log1p(*self.args)
+
+    def _eval_rewrite_as_log(self, arg):
+        return _log1p(arg)
+
+    _eval_rewrite_as_tractable = _eval_rewrite_as_log
+
+    @classmethod
+    def eval(cls, arg):
+        if not arg.is_Float:  # not safe to add 1 to Float
+            return log.eval(arg + S.One)
+        elif arg.is_number:
+            return log.eval(Rational(arg) + S.One)
+
+    def _eval_is_real(self):
+        return (self.args[0] + S.One).is_nonnegative
+
+    def _eval_is_finite(self):
+        if (self.args[0] + S.One).is_zero:
+            return False
+        return self.args[0].is_finite
+
+    def _eval_is_positive(self):
+        return self.args[0].is_positive
+
+    def _eval_is_zero(self):
+        return self.args[0].is_zero
+
+    def _eval_is_nonnegative(self):
+        return self.args[0].is_nonnegative
+
+_Two = S(2)
+
+def _exp2(x):
+    return Pow(_Two, x)
+
+class exp2(Function):
+    """
+    Represents the exponential function with base two.
+
+    The benefit of using ``exp2(x)`` over ``2**x``
+    is that the latter is not as efficient under finite precision
+    arithmetic.
+
+    Examples
+    ========
+    >>> from sympy.abc import x
+    >>> from sympy.codegen.cfunctions import exp2
+    >>> exp2(2).evalf() == 4
+    True
+    >>> exp2(x).diff(x)
+    log(2)*exp2(x)
+
+    See Also
+    ========
+
+    log2
+    """
+    nargs = 1
+
+
+    def fdiff(self, argindex=1):
+        """
+        Returns the first derivative of this function.
+        """
+        if argindex == 1:
+            return self*log(_Two)
+        else:
+            raise ArgumentIndexError(self, argindex)
+
+    def _eval_rewrite_as_Pow(self, arg):
+        return _exp2(arg)
+
+    _eval_rewrite_as_tractable = _eval_rewrite_as_Pow
+
+    def _eval_expand_func(self, **hints):
+        return _exp2(*self.args)
+
+    @classmethod
+    def eval(cls, arg):
+        if arg.is_number:
+            return _exp2(arg)
+
+
+def _log2(x):
+    return log(x)/log(_Two)
+
+
+class log2(Function):
+    """
+    Represents the logarithm function with base two.
+
+    The benefit of using ``log2(x)`` over ``log(x)/log(2)``
+    is that the latter is not as efficient under finite precision
+    arithmetic.
+
+    Examples
+    ========
+    >>> from sympy.abc import x
+    >>> from sympy.codegen.cfunctions import log2
+    >>> log2(4).evalf() == 2
+    True
+    >>> log2(x).diff(x)
+    1/(x*log(2))
+
+    See Also
+    ========
+
+    exp2
+    log10
+    """
+    nargs = 1
+
+    def fdiff(self, argindex=1):
+        """
+        Returns the first derivative of this function.
+        """
+        if argindex == 1:
+            return S.One/(log(_Two)*self.args[0])
+        else:
+            raise ArgumentIndexError(self, argindex)
+
+
+    @classmethod
+    def eval(cls, arg):
+        if arg.is_number:
+            result = log.eval(arg, base=_Two)
+            if result.is_Atom:
+                return result
+        elif arg.is_Pow and arg.base == _Two:
+            return arg.exp
+
+    def _eval_expand_func(self, **hints):
+        return _log2(*self.args)
+
+    def _eval_rewrite_as_log(self, arg):
+        return _log2(arg)
+
+    _eval_rewrite_as_tractable = _eval_rewrite_as_log
+
+
+def _fma(x, y, z):
+    return x*y + z
+
+
+class fma(Function):
+    """
+    Represents "fused multiply add".
+
+    The benefit of using ``fma(x, y, z)`` over ``x*y + z``
+    is that, under finite precision arithmetic, the former is
+    supported by special instructions on some CPUs.
+
+    Examples
+    ========
+    >>> from sympy.abc import x, y, z
+    >>> from sympy.codegen.cfunctions import fma
+    >>> fma(x, y, z).diff(x)
+    y
+
+    """
+    nargs = 3
+
+    def fdiff(self, argindex=1):
+        """
+        Returns the first derivative of this function.
+        """
+        if argindex in (1, 2):
+            return self.args[2 - argindex]
+        elif argindex == 3:
+            return S.One
+        else:
+            raise ArgumentIndexError(self, argindex)
+
+
+    def _eval_expand_func(self, **hints):
+        return _fma(*self.args)
+
+    def _eval_rewrite_as_tractable(self, arg):
+        return _fma(arg)
+
+
+_Ten = S(10)
+
+
+def _log10(x):
+    return log(x)/log(_Ten)
+
+
+class log10(Function):
+    """
+    Represents the logarithm function with base ten.
+
+    Examples
+    ========
+    >>> from sympy.abc import x
+    >>> from sympy.codegen.cfunctions import log10
+    >>> log10(100).evalf() == 2
+    True
+    >>> log10(x).diff(x)
+    1/(x*log(10))
+
+    See Also
+    ========
+
+    log2
+    """
+    nargs = 1
+
+    def fdiff(self, argindex=1):
+        """
+        Returns the first derivative of this function.
+        """
+        if argindex == 1:
+            return S.One/(log(_Ten)*self.args[0])
+        else:
+            raise ArgumentIndexError(self, argindex)
+
+
+    @classmethod
+    def eval(cls, arg):
+        if arg.is_number:
+            result = log.eval(arg, base=_Ten)
+            if result.is_Atom:
+                return result
+        elif arg.is_Pow and arg.base == _Ten:
+            return arg.exp
+
+    def _eval_expand_func(self, **hints):
+        return _log10(*self.args)
+
+    def _eval_rewrite_as_log(self, arg):
+        return _log10(arg)
+
+    _eval_rewrite_as_tractable = _eval_rewrite_as_log
+
+
+def _Sqrt(x):
+    return Pow(x, S.Half)
+
+
+class Sqrt(Function):  # 'sqrt' already defined in sympy.functions.elementary.miscellaneous
+    """
+    Represents the square root function.
+
+    The reason why one would use ``Sqrt(x)`` over ``sqrt(x)``
+    is that the latter is internally represented as ``Pow(x, S.Half)`` which
+    may not be what one wants when doing code-generation.
+
+    Examples
+    ========
+    >>> from sympy.abc import x
+    >>> from sympy.codegen.cfunctions import Sqrt
+    >>> Sqrt(x)
+    Sqrt(x)
+    >>> Sqrt(x).diff(x)
+    1/(2*sqrt(x))
+
+    See Also
+    ========
+
+    Cbrt
+    """
+    nargs = 1
+
+    def fdiff(self, argindex=1):
+        """
+        Returns the first derivative of this function.
+        """
+        if argindex == 1:
+            return Pow(self.args[0], -S.Half)/_Two
+        else:
+            raise ArgumentIndexError(self, argindex)
+
+    def _eval_expand_func(self, **hints):
+        return _Sqrt(*self.args)
+
+    def _eval_rewrite_as_Pow(self, arg):
+        return _Sqrt(arg)
+
+    _eval_rewrite_as_tractable = _eval_rewrite_as_Pow
+
+
+def _Cbrt(x):
+    return Pow(x, Rational(1, 3))
+
+
+class Cbrt(Function):  # 'cbrt' already defined in sympy.functions.elementary.miscellaneous
+    """
+    Represents the cube root function.
+
+    The reason why one would use ``Cbrt(x)`` over ``cbrt(x)``
+    is that the latter is internally represented as ``Pow(x, Rational(1, 3))`` which
+    may not be what one wants when doing code-generation.
+
+    Examples
+    ========
+
+    >>> from sympy.abc import x
+    >>> from sympy.codegen.cfunctions import Cbrt
+    >>> Cbrt(x)
+    Cbrt(x)
+    >>> Cbrt(x).diff(x)
+    1/(3*x**(2/3))
+
+    See Also
+    ========
+
+    Sqrt
+    """
+    nargs = 1
+
+    def fdiff(self, argindex=1):
+        """
+        Returns the first derivative of this function.
+        """
+        if argindex == 1:
+            return Pow(self.args[0], Rational(-_Two/3))/3
+        else:
+            raise ArgumentIndexError(self, argindex)
+
+
+    def _eval_expand_func(self, **hints):
+        return _Cbrt(*self.args)
+
+    def _eval_rewrite_as_Pow(self, arg):
+        return _Cbrt(arg)
+
+    _eval_rewrite_as_tractable = _eval_rewrite_as_Pow
+
+
+def _hypot(x, y):
+    return sqrt(Pow(x, 2) + Pow(y, 2))
+
+
+class hypot(Function):
+    """
+    Represents the hypotenuse function.
+
+    The hypotenuse function is provided by e.g. the math library
+    in the C99 standard, hence one may want to represent the function
+    symbolically when doing code-generation.
+
+    Examples
+    ========
+
+    >>> from sympy.abc import x, y
+    >>> from sympy.codegen.cfunctions import hypot
+    >>> hypot(3, 4).evalf() == 5
+    True
+    >>> hypot(x, y)
+    hypot(x, y)
+    >>> hypot(x, y).diff(x)
+    x/hypot(x, y)
+
+    """
+    nargs = 2
+
+    def fdiff(self, argindex=1):
+        """
+        Returns the first derivative of this function.
+        """
+        if argindex in (1, 2):
+            return 2*self.args[argindex-1]/(_Two*self.func(*self.args))
+        else:
+            raise ArgumentIndexError(self, argindex)
+
+
+    def _eval_expand_func(self, **hints):
+        return _hypot(*self.args)
+
+    def _eval_rewrite_as_Pow(self, arg):
+        return _hypot(arg)
+
+    _eval_rewrite_as_tractable = _eval_rewrite_as_Pow
diff --git a/sympy/core/decorators.py b/sympy/core/decorators.py
index 4b0dacfeaf..47602b0456 100644
--- a/sympy/core/decorators.py
+++ b/sympy/core/decorators.py
@@ -24,6 +24,7 @@ def new_func(*args, **kwargs):
             decorator_kwargs.setdefault('feature', func.__name__)
             SymPyDeprecationWarning(**decorator_kwargs).warn(stacklevel=3)
             return func(*args, **kwargs)
+        new_func._sympy_deprecated_func = func
         return new_func
     return deprecated_decorator
 
diff --git a/sympy/printing/__init__.py b/sympy/printing/__init__.py
index 890d323e7e..0f8c3a5777 100644
--- a/sympy/printing/__init__.py
+++ b/sympy/printing/__init__.py
@@ -6,6 +6,7 @@
 from .mathml import mathml, print_mathml
 from .python import python, print_python
 from .ccode import ccode, print_ccode
+from .cxxcode import cxxcode
 from .fcode import fcode, print_fcode
 from .rcode import rcode, print_rcode
 from .jscode import jscode, print_jscode
diff --git a/sympy/printing/ccode.py b/sympy/printing/ccode.py
index 6b88f4abc7..ee21ea62a9 100644
--- a/sympy/printing/ccode.py
+++ b/sympy/printing/ccode.py
@@ -1,8 +1,8 @@
 """
 C code printer
 
-The CCodePrinter converts single sympy expressions into single C expressions,
-using the functions defined in math.h where possible.
+The C89CodePrinter & C99CodePrinter converts single sympy expressions into
+single C expressions, using the functions defined in math.h where possible.
 
 A complete code generator, which uses ccode extensively, can be found in
 sympy.utilities.codegen. The codegen module can be used to generate complete
@@ -15,16 +15,16 @@
 
 from sympy.core import S
 from sympy.core.compatibility import string_types, range
+from sympy.core.decorators import deprecated
 from sympy.codegen.ast import Assignment
 from sympy.printing.codeprinter import CodePrinter
 from sympy.printing.precedence import precedence
 from sympy.sets.fancysets import Range
 
 # dictionary mapping sympy function to (argument_conditions, C_function).
-# Used in CCodePrinter._print_Function(self)
-known_functions = {
+# Used in C89CodePrinter._print_Function(self)
+known_functions_C89 = {
     "Abs": [(lambda x: not x.is_integer, "fabs")],
-    "gamma": "tgamma",
     "sin": "sin",
     "cos": "cos",
     "tan": "tan",
@@ -34,59 +34,82 @@
     "atan2": "atan2",
     "exp": "exp",
     "log": "log",
-    "erf": "erf",
     "sinh": "sinh",
     "cosh": "cosh",
     "tanh": "tanh",
-    "asinh": "asinh",
-    "acosh": "acosh",
-    "atanh": "atanh",
     "floor": "floor",
     "ceiling": "ceil",
 }
 
+# move to C99 once CCodePrinter is removed:
+_known_functions_C9X = dict(known_functions_C89, **{
+    "asinh": "asinh",
+    "acosh": "acosh",
+    "atanh": "atanh",
+    "erf": "erf",
+    "gamma": "tgamma",
+})
+known_functions = _known_functions_C9X
+
+known_functions_C99 = dict(_known_functions_C9X, **{
+    "erfc": "erfc",
+})
+
 # These are the core reserved words in the C language. Taken from:
-# http://crasseux.com/books/ctutorial/Reserved-words-in-C.html
-
-reserved_words = ['auto',
-                  'if',
-                  'break',
-                  'int',
-                  'case',
-                  'long',
-                  'char',
-                  'register',
-                  'continue',
-                  'return',
-                  'default',
-                  'short',
-                  'do',
-                  'sizeof',
-                  'double',
-                  'static',
-                  'else',
-                  'struct',
-                  'entry',
-                  'switch',
-                  'extern',
-                  'typedef',
-                  'float',
-                  'union',
-                  'for',
-                  'unsigned',
-                  'goto',
-                  'while',
-                  'enum',
-                  'void',
-                  'const',
-                  'signed',
-                  'volatile']
-
-
-class CCodePrinter(CodePrinter):
+# http://en.cppreference.com/w/c/keyword
+
+reserved_words = [
+    'auto', 'break', 'case', 'char', 'const', 'continue', 'default', 'do',
+    'double', 'else', 'enum', 'extern', 'float', 'for', 'goto', 'if', 'int',
+    'long', 'register', 'return', 'short', 'signed', 'sizeof', 'static',
+    'struct', 'entry',  # never standardized, we'll leave it here anyway
+    'switch', 'typedef', 'union', 'unsigned', 'void', 'volatile', 'while'
+]
+
+reserved_words_c99 = ['inline', 'restrict']
+
+def get_math_macros():
+    """ Returns a dictionary with math-related macros from math.h/cmath
+
+    Note that these macros are not strictly required by the C/C++-standard.
+    For MSVC they are enabled by defining "_USE_MATH_DEFINES" (preferably
+    via a compilation flag).
+
+    Returns
+    -------
+    Dictionary mapping sympy expressions to strings (macro names)
+
+    """
+    from sympy.codegen.cfunctions import log2, Sqrt
+    from sympy.functions.elementary.exponential import log
+    from sympy.functions.elementary.miscellaneous import sqrt
+
+    return {
+        S.Exp1: 'M_E',
+        log2(S.Exp1): 'M_LOG2E',
+        1/log(2): 'M_LOG2E',
+        log(2): 'M_LN2',
+        log(10): 'M_LN10',
+        S.Pi: 'M_PI',
+        S.Pi/2: 'M_PI_2',
+        S.Pi/4: 'M_PI_4',
+        1/S.Pi: 'M_1_PI',
+        2/S.Pi: 'M_2_PI',
+        2/sqrt(S.Pi): 'M_2_SQRTPI',
+        2/Sqrt(S.Pi): 'M_2_SQRTPI',
+        sqrt(2): 'M_SQRT2',
+        Sqrt(2): 'M_SQRT2',
+        1/sqrt(2): 'M_SQRT1_2',
+        1/Sqrt(2): 'M_SQRT1_2'
+    }
+
+
+class C89CodePrinter(CodePrinter):
     """A printer to convert python expressions to strings of c code"""
     printmethod = "_ccode"
     language = "C"
+    standard = "C89"
+    reserved_words = set(reserved_words)
 
     _default_settings = {
         'order': None,
@@ -100,13 +123,13 @@ class CCodePrinter(CodePrinter):
         'reserved_word_suffix': '_',
     }
 
+    _ns = ''  # namespace, C++ uses 'std::'
+    _kf = known_functions_C89  # known_functions-dict to copy
+
     def __init__(self, settings={}):
-        CodePrinter.__init__(self, settings)
-        self.known_functions = dict(known_functions)
-        userfuncs = settings.get('user_functions', {})
-        self.known_functions.update(userfuncs)
+        super(C89CodePrinter, self).__init__(settings)
+        self.known_functions = dict(self._kf, **settings.get('user_functions', {}))
         self._dereference = set(settings.get('dereference', []))
-        self.reserved_words = set(reserved_words)
 
     def _rate_index_position(self, p):
         return p*5
@@ -127,19 +150,6 @@ def _traverse_matrix_indices(self, mat):
         rows, cols = mat.shape
         return ((i, j) for i in range(rows) for j in range(cols))
 
-    def _get_loop_opening_ending(self, indices):
-        open_lines = []
-        close_lines = []
-        loopstart = "for (int %(var)s=%(start)s; %(var)s<%(end)s; %(var)s++){"
-        for i in indices:
-            # C arrays start at 0 and end at dimension-1
-            open_lines.append(loopstart % {
-                'var': self._print(i.label),
-                'start': self._print(i.lower),
-                'end': self._print(i.upper + 1)})
-            close_lines.append("}")
-        return open_lines, close_lines
-
     def _print_Pow(self, expr):
         if "Pow" in self.known_functions:
             return self._print_Function(expr)
@@ -147,10 +157,12 @@ def _print_Pow(self, expr):
         if expr.exp == -1:
             return '1.0/%s' % (self.parenthesize(expr.base, PREC))
         elif expr.exp == 0.5:
-            return 'sqrt(%s)' % self._print(expr.base)
+            return '%ssqrt(%s)' % (self._ns, self._print(expr.base))
+        elif expr.exp == S.One/3 and self.standard != 'C89':
+            return '%scbrt(%s)' % (self._ns, self._print(expr.base))
         else:
-            return 'pow(%s, %s)' % (self._print(expr.base),
-                                 self._print(expr.exp))
+            return '%spow(%s, %s)' % (self._ns, self._print(expr.base),
+                                   self._print(expr.exp))
 
     def _print_Rational(self, expr):
         p, q = int(expr.p), int(expr.q)
@@ -223,9 +235,7 @@ def _print_MatrixElement(self, expr):
                 expr.i*expr.parent.shape[1])
 
     def _print_Symbol(self, expr):
-
-        name = super(CCodePrinter, self)._print_Symbol(expr)
-
+        name = super(C89CodePrinter, self)._print_Symbol(expr)
         if expr in self._dereference:
             return '(*{0})'.format(name)
         else:
@@ -265,6 +275,24 @@ def _print_For(self, expr):
     def _print_sign(self, func):
         return '((({0}) > 0) - (({0}) < 0))'.format(self._print(func.args[0]))
 
+    def _print_Max(self, expr):
+        if "Max" in self.known_functions:
+            return self._print_Function(expr)
+        from sympy import Max
+        if len(expr.args) == 1:
+            return self._print(expr.args[0])
+        return "((%(a)s > %(b)s) ? %(a)s : %(b)s)" % {
+            'a': expr.args[0], 'b': self._print(Max(*expr.args[1:]))}
+
+    def _print_Min(self, expr):
+        if "Min" in self.known_functions:
+            return self._print_Function(expr)
+        from sympy import Min
+        if len(expr.args) == 1:
+            return self._print(expr.args[0])
+        return "((%(a)s < %(b)s) ? %(a)s : %(b)s)" % {
+            'a': expr.args[0], 'b': self._print(Min(*expr.args[1:]))}
+
     def indent_code(self, code):
         """Accepts a string of code or a list of code lines"""
 
@@ -276,11 +304,10 @@ def indent_code(self, code):
         inc_token = ('{', '(', '{\n', '(\n')
         dec_token = ('}', ')')
 
-        code = [ line.lstrip(' \t') for line in code ]
+        code = [line.lstrip(' \t') for line in code]
 
-        increase = [ int(any(map(line.endswith, inc_token))) for line in code ]
-        decrease = [ int(any(map(line.startswith, dec_token)))
-                     for line in code ]
+        increase = [int(any(map(line.endswith, inc_token))) for line in code]
+        decrease = [int(any(map(line.startswith, dec_token))) for line in code]
 
         pretty = []
         level = 0
@@ -294,7 +321,106 @@ def indent_code(self, code):
         return pretty
 
 
-def ccode(expr, assign_to=None, **settings):
+class _C9XCodePrinter(object):
+    # Move these methods to C99CodePrinter when removing CCodePrinter
+    def _get_loop_opening_ending(self, indices):
+        open_lines = []
+        close_lines = []
+        loopstart = "for (int %(var)s=%(start)s; %(var)s<%(end)s; %(var)s++){"  # C99
+        for i in indices:
+            # C arrays start at 0 and end at dimension-1
+            open_lines.append(loopstart % {
+                'var': self._print(i.label),
+                'start': self._print(i.lower),
+                'end': self._print(i.upper + 1)})
+            close_lines.append("}")
+        return open_lines, close_lines
+
+
+@deprecated(
+    last_supported_version='1.0',
+    useinstead="C89CodePrinter or C99CodePrinter, e.g. ccode(..., standard='C99')",
+    issue=12220,
+    deprecated_since_version='1.1')
+class CCodePrinter(_C9XCodePrinter, C89CodePrinter):
+    """
+    Deprecated.
+
+    Alias for C89CodePrinter, for backwards compatibility.
+    """
+    _kf = _known_functions_C9X  # known_functions-dict to copy
+
+
+class C99CodePrinter(_C9XCodePrinter, C89CodePrinter):
+    standard = 'C99'
+    reserved_words = set(reserved_words + reserved_words_c99)
+    _kf = known_functions_C99  # known_functions-dict to copy
+
+    def _print_Max(self, expr):
+        if "Max" in self.known_functions:
+            return self._print_Function(expr)
+        from sympy import Max
+        if len(expr.args) == 1:
+            return self._print(expr.args[0])
+        return "%sfmax(%s, %s)" % (self._ns, expr.args[0], self._print(Max(*expr.args[1:])))
+
+    def _print_Min(self, expr):
+        if "Min" in self.known_functions:
+            return self._print_Function(expr)
+        from sympy import Min
+        if len(expr.args) == 1:
+            return self._print(expr.args[0])
+        return "%sfmin(%s, %s)" % (self._ns, expr.args[0], self._print(Min(*expr.args[1:])))
+
+    def _print_Infinity(self, expr):
+        return 'INFINITY'
+
+    def _print_NegativeInfinity(self, expr):
+        return '-INFINITY'
+
+    def _print_NaN(self, expr):
+        return 'NAN'
+
+    def _print_fma(self, expr):  # fused mutiply-add
+        return '{0}fma({1}, {2}, {3})'.format(self._ns, *map(self._print, expr.args))
+
+    def _print_log10(self, expr):  # log10 in C89, but type-generic macro in C99
+        return '{0}log10({1})'.format(self._ns, self._print(expr.args[0]))
+
+    def _print_Sqrt(self, expr):
+        return '{0}sqrt({1})'.format(self._ns, self._print(expr.args[0]))
+
+    def _print_Cbrt(self, expr):
+        return '{0}cbrt({1})'.format(self._ns, self._print(expr.args[0]))
+
+    def _print_hypot(self, expr):
+        return '{0}hypot({1}, {2})'.format(self._ns, *map(self._print, expr.args))
+
+    def _print_expm1(self, expr):
+        return '{0}expm1({1})'.format(self._ns, self._print(expr.args[0]))
+
+    def _print_log1p(self, expr):
+        return '{0}log1p({1})'.format(self._ns, self._print(expr.args[0]))
+
+    def _print_exp2(self, expr):
+        return '{0}exp2({1})'.format(self._ns, self._print(expr.args[0]))
+
+    def _print_log2(self, expr):
+        return '{0}log2({1})'.format(self._ns, self._print(expr.args[0]))
+
+    def _print_loggamma(self, expr):
+        return '{0}lgamma({1})'.format(self._ns, self._print(expr.args[0]))
+
+    # tgamma was already covered by 'known_functions' dict
+
+
+c_code_printers = {
+    'c89': C89CodePrinter,
+    'c99': C99CodePrinter,
+}
+
+
+def ccode(expr, assign_to=None, standard='c99', **settings):
     """Converts an expr to a string of c code
 
     Parameters
@@ -307,6 +433,10 @@ def ccode(expr, assign_to=None, **settings):
         the expression is assigned. Can be a string, ``Symbol``,
         ``MatrixSymbol``, or ``Indexed`` type. This is helpful in case of
         line-wrapping, or for expressions that generate multi-line statements.
+    standard : str, optional
+        String specifying the standard. If your compiler supports a more modern
+        standard you may set this to 'c99' to allow the printer to use more math
+        functions. [default='c89'].
     precision : integer, optional
         The precision for numbers such as pi [default=15].
     user_functions : dict, optional
@@ -338,9 +468,9 @@ def ccode(expr, assign_to=None, **settings):
 
     >>> from sympy import ccode, symbols, Rational, sin, ceiling, Abs, Function
     >>> x, tau = symbols("x, tau")
-    >>> ccode((2*tau)**Rational(7, 2))
+    >>> ccode((2*tau)**Rational(7, 2), standard='C89')
     '8*sqrt(2)*pow(tau, 7.0L/2.0L)'
-    >>> ccode(sin(x), assign_to="s")
+    >>> ccode(sin(x), assign_to="s", standard='C89')
     's = sin(x);'
 
     Simple custom printing can be defined for certain types by passing a
@@ -355,12 +485,12 @@ def ccode(expr, assign_to=None, **settings):
     ...   "func": "f"
     ... }
     >>> func = Function('func')
-    >>> ccode(func(Abs(x) + ceiling(x)), user_functions=custom_functions)
+    >>> ccode(func(Abs(x) + ceiling(x)), standard='C89', user_functions=custom_functions)
     'f(fabs(x) + CEIL(x))'
 
     or if the C-function takes a subset of the original arguments:
 
-    >>> ccode(2**x + 3**x, user_functions={'Pow': [
+    >>> ccode(2**x + 3**x, standard='C99', user_functions={'Pow': [
     ...   (lambda b, e: b == 2, lambda b, e: 'exp2(%s)' % e),
     ...   (lambda b, e: b != 2, 'pow')]})
     'exp2(x) + pow(3, x)'
@@ -374,7 +504,7 @@ def ccode(expr, assign_to=None, **settings):
 
     >>> from sympy import Piecewise
     >>> expr = Piecewise((x + 1, x > 0), (x, True))
-    >>> print(ccode(expr, tau))
+    >>> print(ccode(expr, tau, standard='C89'))
     if (x > 0) {
     tau = x + 1;
     }
@@ -394,7 +524,7 @@ def ccode(expr, assign_to=None, **settings):
     >>> Dy = IndexedBase('Dy', shape=(len_y-1,))
     >>> i = Idx('i', len_y-1)
     >>> e=Eq(Dy[i], (y[i+1]-y[i])/(t[i+1]-t[i]))
-    >>> ccode(e.rhs, assign_to=e.lhs, contract=False)
+    >>> ccode(e.rhs, assign_to=e.lhs, contract=False, standard='C89')
     'Dy[i] = (y[i + 1] - y[i])/(t[i + 1] - t[i]);'
 
     Matrices are also supported, but a ``MatrixSymbol`` of the same dimensions
@@ -404,7 +534,7 @@ def ccode(expr, assign_to=None, **settings):
     >>> from sympy import Matrix, MatrixSymbol
     >>> mat = Matrix([x**2, Piecewise((x + 1, x > 0), (x, True)), sin(x)])
     >>> A = MatrixSymbol('A', 3, 1)
-    >>> print(ccode(mat, A))
+    >>> print(ccode(mat, A, standard='C89'))
     A[0] = pow(x, 2);
     if (x > 0) {
        A[1] = x + 1;
@@ -414,8 +544,7 @@ def ccode(expr, assign_to=None, **settings):
     }
     A[2] = sin(x);
     """
-
-    return CCodePrinter(settings).doprint(expr, assign_to)
+    return c_code_printers[standard.lower()](settings).doprint(expr, assign_to)
 
 
 def print_ccode(expr, **settings):
diff --git a/sympy/printing/codeprinter.py b/sympy/printing/codeprinter.py
index ea9e6a69f2..4f3cd20ca8 100644
--- a/sympy/printing/codeprinter.py
+++ b/sympy/printing/codeprinter.py
@@ -40,7 +40,8 @@ def __init__(self, settings=None):
 
         super(CodePrinter, self).__init__(settings=settings)
 
-        self.reserved_words = set()
+        if not hasattr(self, 'reserved_words'):
+            self.reserved_words = set()
 
     def doprint(self, expr, assign_to=None):
         """
diff --git a/sympy/printing/cxxcode.py b/sympy/printing/cxxcode.py
new file mode 100644
index 0000000000..5fa174b384
--- /dev/null
+++ b/sympy/printing/cxxcode.py
@@ -0,0 +1,128 @@
+from __future__ import (absolute_import, division, print_function)
+"""
+C++ code printer
+"""
+from functools import wraps
+from .ccode import C89CodePrinter, C99CodePrinter
+
+
+# from http://en.cppreference.com/w/cpp/keyword
+reserved = {
+    'C++98': [
+        'and', 'and_eq', 'asm', 'auto', 'bitand', 'bitor', 'bool', 'break',
+        'case', 'catch,', 'char', 'class', 'compl', 'const', 'const_cast',
+        'continue', 'default', 'delete', 'do', 'double', 'dynamic_cast',
+        'else', 'enum', 'explicit', 'export', 'extern', 'false', 'float',
+        'for', 'friend', 'goto', 'if', 'inline', 'int', 'long', 'mutable',
+        'namespace', 'new', 'not', 'not_eq', 'operator', 'or', 'or_eq',
+        'private', 'protected', 'public', 'register', 'reinterpret_cast',
+        'return', 'short', 'signed', 'sizeof', 'static', 'static_cast',
+        'struct', 'switch', 'template', 'this', 'throw', 'true', 'try',
+        'typedef', 'typeid', 'typename', 'union', 'unsigned', 'using',
+        'virtual', 'void', 'volatile', 'wchar_t', 'while', 'xor', 'xor_eq'
+    ]
+}
+
+reserved['C++11'] = reserved['C++98'][:] + [
+    'alignas', 'alignof', 'char16_t', 'char32_t', 'constexpr', 'decltype',
+    'noexcept', 'nullptr', 'static_assert', 'thread_local'
+]
+reserved['C++17'] = []
+# TM TS: atomic_cancel, atomic_commit, atomic_noexcept, synchronized
+# concepts TS: concept, requires
+# module TS: import, module
+
+
+_math_functions = {
+    'C++98': {
+        'Mod': 'fmod',
+        'ceiling': 'ceil',
+    },
+    'C++11': {
+        'gamma': 'tgamma',
+    },
+    'C++17': {
+        'beta': 'beta',
+        'Ei': 'expint',
+        'zeta': 'riemann_zeta',
+    }
+}
+
+# from http://en.cppreference.com/w/cpp/header/cmath
+for k in ('Abs', 'exp', 'log', 'log10', 'sqrt', 'sin', 'cos', 'tan',  # 'Pow'
+          'asin', 'acos', 'atan', 'atan2', 'sinh', 'cosh', 'tanh', 'floor'):
+    _math_functions['C++98'][k] = k.lower()
+
+
+for k in ('asinh', 'acosh', 'atanh', 'erf', 'erfc'):
+    _math_functions['C++11'][k] = k.lower()
+
+
+def _attach_print_method(cls, sympy_name, func_name):
+    meth_name = '_print_%s' % sympy_name
+    if hasattr(cls, meth_name):
+        raise ValueError("Edit method (or subclass) instead of overwriting.")
+    def _print_method(self, expr):
+        return '{0}{1}({2})'.format(self._ns, func_name, ', '.join(map(self._print, expr.args)))
+    _print_method.__doc__ = "Prints code for %s" % k
+    setattr(cls, meth_name, _print_method)
+
+
+def _attach_print_methods(cls, cont):
+    for sympy_name, cxx_name in cont[cls.standard].items():
+        _attach_print_method(cls, sympy_name, cxx_name)
+
+
+class _CXXCodePrinterBase(object):
+    printmethod = "_cxxcode"
+    language = 'C++'
+    _ns = 'std::'  # namespace
+
+    def __init__(self, settings=None):
+        super(_CXXCodePrinterBase, self).__init__(settings or {})
+
+    def _print_Max(self, expr):
+        from sympy import Max
+        if len(expr.args) == 1:
+            return self._print(expr.args[0])
+        return "%smax(%s, %s)" % (self._ns, expr.args[0], self._print(Max(*expr.args[1:])))
+
+    def _print_Min(self, expr):
+        from sympy import Min
+        if len(expr.args) == 1:
+            return self._print(expr.args[0])
+        return "%smin(%s, %s)" % (self._ns, expr.args[0], self._print(Min(*expr.args[1:])))
+
+
+class CXX98CodePrinter(_CXXCodePrinterBase, C89CodePrinter):
+    standard = 'C++98'
+    reserved_words = set(reserved['C++98'])
+
+
+_attach_print_methods(CXX98CodePrinter, _math_functions)
+
+
+class CXX11CodePrinter(_CXXCodePrinterBase, C99CodePrinter):
+    standard = 'C++11'
+    reserved_words = set(reserved['C++11'])
+
+
+_attach_print_methods(CXX11CodePrinter, _math_functions)
+
+
+class CXX17CodePrinter(_CXXCodePrinterBase, C99CodePrinter):
+    standard = 'C++17'
+    reserved_words = set(reserved['C++17'])
+
+
+_attach_print_methods(CXX17CodePrinter, _math_functions)
+
+cxx_code_printers = {
+    'c++98': CXX98CodePrinter,
+    'c++11': CXX11CodePrinter,
+    'c++17': CXX17CodePrinter
+}
+
+def cxxcode(expr, assign_to=None, standard='c++11', **settings):
+    """ C++ equivalent of :func:`sympy.ccode`. """
+    return cxx_code_printers[standard.lower()](settings).doprint(expr, assign_to)
diff --git a/sympy/printing/lambdarepr.py b/sympy/printing/lambdarepr.py
index 8b26deb815..faee21af12 100644
--- a/sympy/printing/lambdarepr.py
+++ b/sympy/printing/lambdarepr.py
@@ -252,6 +252,33 @@ def _print_Min(self, expr):
     def _print_Max(self, expr):
         return '{0}(({1}))'.format('amax', ','.join(self._print(i) for i in expr.args))
 
+    def _print_Pow(self, expr):
+        if expr.exp == 0.5:
+            return '{0}({1})'.format('sqrt', self._print(expr.base))
+        else:
+            return super(NumPyPrinter, self)._print_Pow(expr)
+
+    def _print_log10(self, expr):  # log10 in C89, but type-generic macro in C99
+        return 'log10({0})'.format(self._print(expr.args[0]))
+
+    def _print_Sqrt(self, expr):
+        return 'sqrt({0})'.format(self._print(expr.args[0]))
+
+    def _print_hypot(self, expr):
+        return 'hypot({0}, {1})'.format(*map(self._print, expr.args))
+
+    def _print_expm1(self, expr):
+        return 'expm1({0})'.format(self._print(expr.args[0]))
+
+    def _print_log1p(self, expr):
+        return 'log1p({0})'.format(self._print(expr.args[0]))
+
+    def _print_exp2(self, expr):
+        return 'exp2({0})'.format(self._print(expr.args[0]))
+
+    def _print_log2(self, expr):
+        return 'log2({0})'.format(self._print(expr.args[0]))
+
 
 # numexpr works by altering the string passed to numexpr.evaluate
 # rather than by populating a namespace.  Thus a special printer...
diff --git a/sympy/utilities/autowrap.py b/sympy/utilities/autowrap.py
index 950e1ffff8..2f47c36019 100644
--- a/sympy/utilities/autowrap.py
+++ b/sympy/utilities/autowrap.py
@@ -84,7 +84,7 @@
 from sympy.tensor.indexed import Idx, IndexedBase
 from sympy.utilities.codegen import (make_routine, get_code_generator,
             OutputArgument, InOutArgument, InputArgument,
-            CodeGenArgumentListError, Result, ResultBase, CCodeGen)
+            CodeGenArgumentListError, Result, ResultBase, C99CodeGen)
 from sympy.utilities.lambdify import implemented_function
 from sympy.utilities.decorator import doctest_depends_on
 
@@ -430,9 +430,9 @@ def _get_code_wrapper_class(backend):
 # Here we define a lookup of backends -> tuples of languages. For now, each
 # tuple is of length 1, but if a backend supports more than one language,
 # the most preferable language is listed first.
-_lang_lookup = {'CYTHON': ('C',),
+_lang_lookup = {'CYTHON': ('C99', 'C89', 'C'),
                 'F2PY': ('F95',),
-                'NUMPY': ('C',),
+                'NUMPY': ('C99', 'C89', 'C'),
                 'DUMMY': ('F95',)}     # Dummy here just for testing
 
 def _infer_language(backend):
@@ -893,11 +893,11 @@ def ufuncify(args, expr, language=None, backend='numpy', tempdir=None,
     >>> import numpy as np
     >>> f = ufuncify((x, y), y + x**2)
     >>> type(f)
-    numpy.ufunc
+    <class 'numpy.ufunc'>
     >>> f([1, 2, 3], 2)
-    array([ 3.,  6.,  11.])
+    array([  3.,   6.,  11.])
     >>> f(np.arange(5), 3)
-    array([ 3.,  4.,  7.,  12.,  19.])
+    array([  3.,   4.,   7.,  12.,  19.])
 
     For the F2Py and Cython backends, inputs are required to be equal length
     1-dimensional arrays. The F2Py backend will perform type conversion, but
@@ -905,15 +905,15 @@ def ufuncify(args, expr, language=None, backend='numpy', tempdir=None,
 
     >>> f_fortran = ufuncify((x, y), y + x**2, backend='F2Py')
     >>> f_fortran(1, 2)
-    3
-    >>> f_fortran(numpy.array([1, 2, 3]), numpy.array([1.0, 2.0, 3.0]))
-    array([2.,  6.,  12.])
+    array([ 3.])
+    >>> f_fortran(np.array([1, 2, 3]), np.array([1.0, 2.0, 3.0]))
+    array([  2.,   6.,  12.])
     >>> f_cython = ufuncify((x, y), y + x**2, backend='Cython')
-    >>> f_cython(1, 2)
+    >>> f_cython(1, 2)  # doctest: +ELLIPSIS
     Traceback (most recent call last):
-    File "<stdin>", line 1, in <module>
+      ...
     TypeError: Argument '_x' has incorrect type (expected numpy.ndarray, got int)
-    >>> f_cython(numpy.array([1.0]), numpy.array([2.0]))
+    >>> f_cython(np.array([1.0]), np.array([2.0]))
     array([ 3.])
     """
 
@@ -938,7 +938,7 @@ def ufuncify(args, expr, language=None, backend='numpy', tempdir=None,
         helps = []
         for name, expr, args in helpers:
             helps.append(make_routine(name, expr, args))
-        code_wrapper = UfuncifyCodeWrapper(CCodeGen("ufuncify"), tempdir,
+        code_wrapper = UfuncifyCodeWrapper(C99CodeGen("ufuncify"), tempdir,
                                            flags, verbose)
         if not isinstance(expr, (list, tuple)):
             expr = [expr]
diff --git a/sympy/utilities/codegen.py b/sympy/utilities/codegen.py
index 27e31b030e..0b60e3fe2c 100644
--- a/sympy/utilities/codegen.py
+++ b/sympy/utilities/codegen.py
@@ -87,7 +87,7 @@
 from sympy.core import Symbol, S, Expr, Tuple, Equality, Function
 from sympy.core.compatibility import is_sequence, StringIO, string_types
 from sympy.printing.codeprinter import AssignmentError
-from sympy.printing.ccode import ccode, CCodePrinter
+from sympy.printing.ccode import ccode, c_code_printers
 from sympy.printing.fcode import fcode, FCodePrinter
 from sympy.printing.julia import julia_code, JuliaCodePrinter
 from sympy.printing.octave import octave_code, OctaveCodePrinter
@@ -760,6 +760,11 @@ class CCodeGen(CodeGen):
 
     code_extension = "c"
     interface_extension = "h"
+    standard = 'c99'
+
+    def _ccode(self, *args, **kwargs):
+        kwargs['standard'] = kwargs.get('standard', self.standard)
+        return ccode(*args, **kwargs)
 
     def _get_header(self):
         """Writes a common header for the generated files."""
@@ -790,7 +795,7 @@ def get_prototype(self, routine):
 
         type_args = []
         for arg in routine.arguments:
-            name = ccode(arg.name)
+            name = self._ccode(arg.name)
             if arg.dimensions or isinstance(arg, ResultBase):
                 type_args.append((arg.get_datatype('C'), "*%s" % name))
             else:
@@ -842,13 +847,13 @@ def _call_printer(self, routine):
                 assign_to = result.result_var
 
             try:
-                constants, not_c, c_expr = ccode(result.expr, human=False,
+                constants, not_c, c_expr = self._ccode(result.expr, human=False,
                         assign_to=assign_to, dereference=dereference)
             except AssignmentError:
                 assign_to = result.result_var
                 code_lines.append(
                     "%s %s;\n" % (result.get_datatype('c'), str(assign_to)))
-                constants, not_c, c_expr = ccode(result.expr, human=False,
+                constants, not_c, c_expr = self._ccode(result.expr, human=False,
                         assign_to=assign_to, dereference=dereference)
 
             for name, value in sorted(constants, key=str):
@@ -860,7 +865,7 @@ def _call_printer(self, routine):
         return code_lines
 
     def _indent_code(self, codelines):
-        p = CCodePrinter()
+        p = c_code_printers[self.standard.lower()]()
         return p.indent_code(codelines)
 
     def _get_routine_ending(self, routine):
@@ -925,6 +930,11 @@ def dump_h(self, routines, f, prefix, header=True, empty=True):
     # functions it has to call.
     dump_fns = [dump_c, dump_h]
 
+class C89CodeGen(CCodeGen):
+    standard = 'C89'
+
+class C99CodeGen(CCodeGen):
+    standard = 'C99'
 
 class FCodeGen(CodeGen):
     """Generator for Fortran 95 code
@@ -1593,8 +1603,16 @@ def dump_m(self, routines, f, prefix, header=True, empty=True, inline=True):
     dump_fns = [dump_m]
 
 
-def get_code_generator(language, project):
-    CodeGenClass = {"C": CCodeGen, "F95": FCodeGen, "JULIA": JuliaCodeGen,
+def get_code_generator(language, project, standard=None):
+    if language == 'C':
+        if standard is None:
+            pass
+        elif standard.lower() == 'c89':
+            language = 'C89'
+        elif standard.lower() == 'c99':
+            language = 'C99'
+    CodeGenClass = {"C": CCodeGen, "C89": C89CodeGen, "C99": C99CodeGen,
+                    "F95": FCodeGen, "JULIA": JuliaCodeGen,
                     "OCTAVE": OctaveCodeGen}.get(language.upper())
     if CodeGenClass is None:
         raise ValueError("Language '%s' is not supported." % language)
@@ -1608,7 +1626,7 @@ def get_code_generator(language, project):
 
 def codegen(name_expr, language, prefix=None, project="project",
             to_files=False, header=True, empty=True, argument_sequence=None,
-            global_vars=None):
+            global_vars=None, standard=None):
     """Generate source code for expressions in a given language.
 
     Parameters
@@ -1665,17 +1683,18 @@ def codegen(name_expr, language, prefix=None, project="project",
     >>> from sympy.utilities.codegen import codegen
     >>> from sympy.abc import x, y, z
     >>> [(c_name, c_code), (h_name, c_header)] = codegen(
-    ...     ("f", x+y*z), "C", "test", header=False, empty=False)
+    ...     ("f", x+y*z), "C89", "test", header=False, empty=False)
     >>> print(c_name)
     test.c
     >>> print(c_code)
     #include "test.h"
     #include <math.h>
     double f(double x, double y, double z) {
-      double f_result;
-      f_result = x + y*z;
-      return f_result;
+       double f_result;
+       f_result = x + y*z;
+       return f_result;
     }
+    <BLANKLINE>
     >>> print(h_name)
     test.h
     >>> print(c_header)
@@ -1683,6 +1702,7 @@ def codegen(name_expr, language, prefix=None, project="project",
     #define PROJECT__TEST__H
     double f(double x, double y, double z);
     #endif
+    <BLANKLINE>
 
     Another example using Equality objects to give named outputs.  Here the
     filename (prefix) is taken from the first (name, expr) pair.
@@ -1691,7 +1711,7 @@ def codegen(name_expr, language, prefix=None, project="project",
     >>> from sympy import Eq
     >>> [(c_name, c_code), (h_name, c_header)] = codegen(
     ...      [("myfcn", x + y), ("fcn2", [Eq(f, 2*x), Eq(g, y)])],
-    ...      "C", header=False, empty=False)
+    ...      "C99", header=False, empty=False)
     >>> print(c_name)
     myfcn.c
     >>> print(c_code)
@@ -1706,6 +1726,7 @@ def codegen(name_expr, language, prefix=None, project="project",
        (*f) = 2*x;
        (*g) = y;
     }
+    <BLANKLINE>
 
     If the generated function(s) will be part of a larger project where various
     global variables have been defined, the 'global_vars' option can be used
@@ -1723,11 +1744,12 @@ def codegen(name_expr, language, prefix=None, project="project",
     REAL*8, intent(in) :: y
     f = x + y*z
     end function
+    <BLANKLINE>
 
     """
 
     # Initialize the code generator.
-    code_gen = get_code_generator(language, project)
+    code_gen = get_code_generator(language, project, standard)
 
     if isinstance(name_expr[0], string_types):
         # single tuple is given, turn it into a singleton list with a tuple.


Test patch:
diff --git a/conftest.py b/conftest.py
new file mode 100644
index 0000000000..72b3368ff5
--- /dev/null
+++ b/conftest.py
@@ -0,0 +1,22 @@
+# -*- coding: utf-8 -*-
+
+from __future__ import print_function, division, absolute_import
+
+import pytest
+
+
+def pytest_addoption(parser):
+    parser.addoption("--slow", dest="runslow", action="store_true",
+                     help="allow slow tests to run")
+
+
+def pytest_configure(config):
+    # register an additional marker
+    config.addinivalue_line("markers", "slow: slow test")
+
+
+def pytest_runtest_setup(item):
+    if not isinstance(item, pytest.Function):
+        return
+    if not item.config.getvalue("runslow") and hasattr(item.obj, 'slow'):
+        pytest.skip("slow test: pass --slow to run")
diff --git a/sympy/codegen/tests/test_cfunctions.py b/sympy/codegen/tests/test_cfunctions.py
new file mode 100644
index 0000000000..cb6ac7311b
--- /dev/null
+++ b/sympy/codegen/tests/test_cfunctions.py
@@ -0,0 +1,161 @@
+from sympy import symbols, Symbol, exp, log, pi, Rational, S
+from sympy.codegen.cfunctions import (
+    expm1, log1p, exp2, log2, fma, log10, Sqrt, Cbrt, hypot
+)
+
+
+def test_expm1():
+    # Eval
+    assert expm1(0) == 0
+
+    x = Symbol('x', real=True, finite=True)
+
+    # Expand and rewrite
+    assert expm1(x).expand(func=True) - exp(x) == -1
+    assert expm1(x).rewrite('tractable') - exp(x) == -1
+    assert expm1(x).rewrite('exp') - exp(x) == -1
+
+    # Precision
+    assert not ((exp(1e-10).evalf() - 1) - 1e-10 - 5e-21) < 1e-22  # for comparison
+    assert abs(expm1(1e-10).evalf() - 1e-10 - 5e-21) < 1e-22
+
+    # Properties
+    assert expm1(x).is_real
+    assert expm1(x).is_finite
+
+    # Diff
+    assert expm1(42*x).diff(x) - 42*exp(42*x) == 0
+    assert expm1(42*x).diff(x) - expm1(42*x).expand(func=True).diff(x) == 0
+
+
+def test_log1p():
+    # Eval
+    assert log1p(0) == 0
+    d = S(10)
+    assert log1p(d**-1000) - log(d**1000 + 1) + log(d**1000) == 0
+
+    x = Symbol('x', real=True, finite=True)
+
+    # Expand and rewrite
+    assert log1p(x).expand(func=True) - log(x + 1) == 0
+    assert log1p(x).rewrite('tractable') - log(x + 1) == 0
+    assert log1p(x).rewrite('log') - log(x + 1) == 0
+
+    # Precision
+    assert not abs(log(1e-99 + 1).evalf() - 1e-99) < 1e-100  # for comparison
+    assert abs(log1p(1e-99).evalf() - 1e-99) < 1e-100
+
+    # Properties
+    assert log1p(-2**(-S(1)/2)).is_real
+
+    assert not log1p(-1).is_finite
+    assert log1p(pi).is_finite
+
+    assert not log1p(x).is_positive
+    assert log1p(Symbol('y', positive=True)).is_positive
+
+    assert not log1p(x).is_zero
+    assert log1p(Symbol('z', zero=True)).is_zero
+
+    assert not log1p(x).is_nonnegative
+    assert log1p(Symbol('o', nonnegative=True)).is_nonnegative
+
+    # Diff
+    assert log1p(42*x).diff(x) - 42/(42*x + 1) == 0
+    assert log1p(42*x).diff(x) - log1p(42*x).expand(func=True).diff(x) == 0
+
+
+def test_exp2():
+    # Eval
+    assert exp2(2) == 4
+
+    x = Symbol('x', real=True, finite=True)
+
+    # Expand
+    assert exp2(x).expand(func=True) - 2**x == 0
+
+    # Diff
+    assert exp2(42*x).diff(x) - 42*exp2(42*x)*log(2) == 0
+    assert exp2(42*x).diff(x) - exp2(42*x).diff(x) == 0
+
+
+def test_log2():
+    # Eval
+    assert log2(8) == 3
+    assert log2(pi) != log(pi)/log(2)  # log2 should *save* (CPU) instructions
+
+    x = Symbol('x', real=True, finite=True)
+    assert log2(x) != log(x)/log(2)
+    assert log2(2**x) == x
+
+    # Expand
+    assert log2(x).expand(func=True) - log(x)/log(2) == 0
+
+    # Diff
+    assert log2(42*x).diff() - 1/(log(2)*x) == 0
+    assert log2(42*x).diff() - log2(42*x).expand(func=True).diff(x) == 0
+
+
+def test_fma():
+    x, y, z = symbols('x y z')
+
+    # Expand
+    assert fma(x, y, z).expand(func=True) - x*y - z == 0
+
+    expr = fma(17*x, 42*y, 101*z)
+
+    # Diff
+    assert expr.diff(x) - expr.expand(func=True).diff(x) == 0
+    assert expr.diff(y) - expr.expand(func=True).diff(y) == 0
+    assert expr.diff(z) - expr.expand(func=True).diff(z) == 0
+
+    assert expr.diff(x) - 17*42*y == 0
+    assert expr.diff(y) - 17*42*x == 0
+    assert expr.diff(z) - 101 == 0
+
+
+def test_log10():
+    x = Symbol('x')
+
+    # Expand
+    assert log10(x).expand(func=True) - log(x)/log(10) == 0
+
+    # Diff
+    assert log10(42*x).diff(x) - 1/(log(10)*x) == 0
+    assert log10(42*x).diff(x) - log10(42*x).expand(func=True).diff(x) == 0
+
+
+def test_Cbrt():
+    x = Symbol('x')
+
+    # Expand
+    assert Cbrt(x).expand(func=True) - x**Rational(1, 3) == 0
+
+    # Diff
+    assert Cbrt(42*x).diff(x) - 42*(42*x)**(Rational(1, 3) - 1)/3 == 0
+    assert Cbrt(42*x).diff(x) - Cbrt(42*x).expand(func=True).diff(x) == 0
+
+
+def test_Sqrt():
+    x = Symbol('x')
+
+    # Expand
+    assert Sqrt(x).expand(func=True) - x**Rational(1, 2) == 0
+
+    # Diff
+    assert Sqrt(42*x).diff(x) - 42*(42*x)**(Rational(1, 2) - 1)/2 == 0
+    assert Sqrt(42*x).diff(x) - Sqrt(42*x).expand(func=True).diff(x) == 0
+
+
+def test_hypot():
+    x, y = symbols('x y')
+
+    # Expand
+    assert hypot(x, y).expand(func=True) - (x**2 + y**2)**Rational(1, 2) == 0
+
+    # Diff
+    assert hypot(17*x, 42*y).diff(x).expand(func=True) - hypot(17*x, 42*y).expand(func=True).diff(x) == 0
+    assert hypot(17*x, 42*y).diff(y).expand(func=True) - hypot(17*x, 42*y).expand(func=True).diff(y) == 0
+
+    assert hypot(17*x, 42*y).diff(x).expand(func=True) - 2*17*17*x*((17*x)**2 + (42*y)**2)**Rational(-1, 2)/2 == 0
+    assert hypot(17*x, 42*y).diff(y).expand(func=True) - 2*42*42*y*((17*x)**2 + (42*y)**2)**Rational(-1, 2)/2 == 0
diff --git a/sympy/core/tests/test_args.py b/sympy/core/tests/test_args.py
index 3f77991a40..ed5cfa68f9 100644
--- a/sympy/core/tests/test_args.py
+++ b/sympy/core/tests/test_args.py
@@ -54,6 +54,8 @@ def test_all_classes_are_tested():
 
             def is_Basic(name):
                 cls = getattr(mod, name)
+                if hasattr(cls, '_sympy_deprecated_func'):
+                    cls = cls._sympy_deprecated_func
                 return issubclass(cls, Basic)
 
             names = list(filter(is_Basic, names))
@@ -3759,6 +3761,42 @@ def test_sympy__codegen__ast__Assignment():
     from sympy.codegen.ast import Assignment
     assert _test_args(Assignment(x, y))
 
+def test_sympy__codegen__cfunctions__expm1():
+    from sympy.codegen.cfunctions import expm1
+    assert _test_args(expm1(x))
+
+def test_sympy__codegen__cfunctions__log1p():
+    from sympy.codegen.cfunctions import log1p
+    assert _test_args(log1p(x))
+
+def test_sympy__codegen__cfunctions__exp2():
+    from sympy.codegen.cfunctions import exp2
+    assert _test_args(exp2(x))
+
+def test_sympy__codegen__cfunctions__log2():
+    from sympy.codegen.cfunctions import log2
+    assert _test_args(log2(x))
+
+def test_sympy__codegen__cfunctions__fma():
+    from sympy.codegen.cfunctions import fma
+    assert _test_args(fma(x, y, z))
+
+def test_sympy__codegen__cfunctions__log10():
+    from sympy.codegen.cfunctions import log10
+    assert _test_args(log10(x))
+
+def test_sympy__codegen__cfunctions__Sqrt():
+    from sympy.codegen.cfunctions import Sqrt
+    assert _test_args(Sqrt(x))
+
+def test_sympy__codegen__cfunctions__Cbrt():
+    from sympy.codegen.cfunctions import Cbrt
+    assert _test_args(Cbrt(x))
+
+def test_sympy__codegen__cfunctions__hypot():
+    from sympy.codegen.cfunctions import hypot
+    assert _test_args(hypot(x, y))
+
 
 def test_sympy__vector__coordsysrect__CoordSysCartesian():
     from sympy.vector.coordsysrect import CoordSysCartesian
diff --git a/sympy/external/tests/test_autowrap.py b/sympy/external/tests/test_autowrap.py
index 48827cbacf..8bd1ad7cee 100644
--- a/sympy/external/tests/test_autowrap.py
+++ b/sympy/external/tests/test_autowrap.py
@@ -1,10 +1,12 @@
 import sympy
 import tempfile
 import os
+import warnings
 from sympy import symbols, Eq
 from sympy.external import import_module
 from sympy.tensor import IndexedBase, Idx
 from sympy.utilities.autowrap import autowrap, ufuncify, CodeWrapError
+from sympy.utilities.exceptions import SymPyDeprecationWarning
 from sympy.utilities.pytest import skip
 
 numpy = import_module('numpy', min_module_version='1.6.1')
@@ -176,31 +178,35 @@ def test_ufuncify_f95_f2py():
 
 def test_wrap_twice_c_cython():
     has_module('Cython')
-    runtest_autowrap_twice('C', 'cython')
+    with warnings.catch_warnings():
+        warnings.filterwarnings("ignore", category=SymPyDeprecationWarning)
+        runtest_autowrap_twice('C', 'cython')
 
 
 def test_autowrap_trace_C_Cython():
     has_module('Cython')
-    runtest_autowrap_trace('C', 'cython')
+    runtest_autowrap_trace('C99', 'cython')
 
 
 def test_autowrap_matrix_vector_C_cython():
     has_module('Cython')
-    runtest_autowrap_matrix_vector('C', 'cython')
+    runtest_autowrap_matrix_vector('C99', 'cython')
 
 
 def test_autowrap_matrix_matrix_C_cython():
     has_module('Cython')
-    runtest_autowrap_matrix_matrix('C', 'cython')
+    runtest_autowrap_matrix_matrix('C99', 'cython')
 
 
 def test_ufuncify_C_Cython():
     has_module('Cython')
-    runtest_ufuncify('C', 'cython')
+    with warnings.catch_warnings():
+        warnings.filterwarnings("ignore", category=SymPyDeprecationWarning)
+        runtest_ufuncify('C99', 'cython')
 
 def test_issue_10274_C_cython():
     has_module('Cython')
-    runtest_issue_10274('C', 'cython')
+    runtest_issue_10274('C89', 'cython')
 
 # Numpy
 
@@ -208,4 +214,6 @@ def test_ufuncify_numpy():
     # This test doesn't use Cython, but if Cython works, then there is a valid
     # C compiler, which is needed.
     has_module('Cython')
-    runtest_ufuncify('C', 'numpy')
+    with warnings.catch_warnings():
+        warnings.filterwarnings("ignore", category=SymPyDeprecationWarning)
+        runtest_ufuncify('C99', 'numpy')
diff --git a/sympy/external/tests/test_codegen.py b/sympy/external/tests/test_codegen.py
index e131fe49bf..24c4dba08a 100644
--- a/sympy/external/tests/test_codegen.py
+++ b/sympy/external/tests/test_codegen.py
@@ -47,7 +47,7 @@
 end program
 """
 
-main_template['C'] = """
+main_template['C89'] = """
 #include "codegen.h"
 #include <stdio.h>
 #include <math.h>
@@ -60,16 +60,17 @@
   return result;
 }
 """
-
+main_template['C99'] = main_template['C89']
 # templates for the numerical tests
 
 numerical_test_template = {}
-numerical_test_template['C'] = """
+numerical_test_template['C89'] = """
   if (fabs(%(call)s)>%(threshold)s) {
     printf("Numerical validation failed: %(call)s=%%e threshold=%(threshold)s\\n", %(call)s);
     result = -1;
   }
 """
+numerical_test_template['C99'] = numerical_test_template['C89']
 
 numerical_test_template['F95'] = """
   if (abs(%(call)s)>%(threshold)s) then
@@ -106,7 +107,8 @@
 ]
 
 combinations_lang_compiler = [
-    ('C', 'cc'),
+    ('C89', 'cc'),
+    ('C99', 'cc'),
     ('F95', 'ifort'),
     ('F95', 'gfortran'),
     ('F95', 'g95')
@@ -175,7 +177,7 @@ def run_test(label, routines, numerical_tests, language, commands, friendly=True
 
     if language == "F95":
         f_name = "main.f90"
-    elif language == "C":
+    elif language.startswith("C"):
         f_name = "main.c"
     else:
         raise NotImplementedError(
@@ -249,7 +251,7 @@ def is_feasible(language, commands):
     ]
     try:
         run_test("is_feasible", [routine], numerical_tests, language, commands,
-                friendly=False)
+                 friendly=False)
         return True
     except AssertionError:
         return False
@@ -265,10 +267,14 @@ def is_feasible(language, commands):
 
 # We test all language-compiler combinations, just to report what is skipped
 
+def test_C89_cc():
+    if ("C89", 'cc') in invalid_lang_compilers:
+        skip("`cc' command didn't work as expected (C89)")
+
 
-def test_C_cc():
-    if ("C", 'cc') in invalid_lang_compilers:
-        skip("`cc' command didn't work as expected")
+def test_C99_cc():
+    if ("C99", 'cc') in invalid_lang_compilers:
+        skip("`cc' command didn't work as expected (C99)")
 
 
 def test_F95_ifort():
@@ -323,7 +329,7 @@ def test_intrinsic_math1_codegen():
             expected = N(expr.subs(x, xval))
             numerical_tests.append((name, (xval,), expected, 1e-14))
     for lang, commands in valid_lang_commands:
-        if lang == "C":
+        if lang.startswith("C"):
             name_expr_C = [("test_floor", floor(x)), ("test_ceil", ceiling(x))]
         else:
             name_expr_C = []
diff --git a/sympy/printing/tests/test_ccode.py b/sympy/printing/tests/test_ccode.py
index 76fe153d5d..86a46ade15 100644
--- a/sympy/printing/tests/test_ccode.py
+++ b/sympy/printing/tests/test_ccode.py
@@ -1,13 +1,16 @@
+import warnings
 from sympy.core import (pi, oo, symbols, Rational, Integer,
-                        GoldenRatio, EulerGamma, Catalan, Lambda, Dummy, Eq)
+                        GoldenRatio, EulerGamma, Catalan, Lambda, Dummy, Eq, nan)
 from sympy.functions import (Piecewise, sin, cos, Abs, exp, ceiling, sqrt,
-                             gamma, sign, Max)
+                             gamma, loggamma, sign, Max, Min)
 from sympy.sets import Range
 from sympy.logic import ITE
 from sympy.codegen import For, aug_assign, Assignment
 from sympy.utilities.pytest import raises
-from sympy.printing.ccode import CCodePrinter
+from sympy.printing.ccode import CCodePrinter, C89CodePrinter, C99CodePrinter, get_math_macros
+from sympy.codegen.cfunctions import expm1, log1p, exp2, log2, fma, log10, Cbrt, hypot, Sqrt
 from sympy.utilities.lambdify import implemented_function
+from sympy.utilities.exceptions import SymPyDeprecationWarning
 from sympy.tensor import IndexedBase, Idx
 from sympy.matrices import Matrix, MatrixSymbol
 
@@ -20,6 +23,7 @@ def test_printmethod():
     class fabs(Abs):
         def _ccode(self, printer):
             return "fabs(%s)" % printer._print(self.args[0])
+
     assert ccode(fabs(x)) == "fabs(x)"
 
 
@@ -56,8 +60,10 @@ def test_ccode_Max():
 def test_ccode_constants_mathh():
     assert ccode(exp(1)) == "M_E"
     assert ccode(pi) == "M_PI"
-    assert ccode(oo) == "HUGE_VAL"
-    assert ccode(-oo) == "-HUGE_VAL"
+    assert ccode(oo, standard='c89') == "HUGE_VAL"
+    assert ccode(-oo, standard='c89') == "-HUGE_VAL"
+    assert ccode(oo) == "INFINITY"
+    assert ccode(-oo, standard='c99') == "-INFINITY"
 
 
 def test_ccode_constants_other():
@@ -103,6 +109,8 @@ def test_ccode_inline_function():
 
 
 def test_ccode_exceptions():
+    assert ccode(gamma(x), standard='C99') == "tgamma(x)"
+    assert 'not supported in c' in ccode(gamma(x), standard='C89').lower()
     assert ccode(ceiling(x)) == "ceil(x)"
     assert ccode(Abs(x)) == "fabs(x)"
     assert ccode(gamma(x)) == "tgamma(x)"
@@ -243,17 +251,21 @@ def test_ccode_Indexed():
     from sympy import symbols
     n, m, o = symbols('n m o', integer=True)
     i, j, k = Idx('i', n), Idx('j', m), Idx('k', o)
-    p = CCodePrinter()
-    p._not_c = set()
 
     x = IndexedBase('x')[j]
-    assert p._print_Indexed(x) == 'x[j]'
     A = IndexedBase('A')[i, j]
-    assert p._print_Indexed(A) == 'A[%s]' % (m*i+j)
     B = IndexedBase('B')[i, j, k]
-    assert p._print_Indexed(B) == 'B[%s]' % (i*o*m+j*o+k)
 
-    assert p._not_c == set()
+    with warnings.catch_warnings():
+        warnings.filterwarnings("ignore", category=SymPyDeprecationWarning)
+        p = CCodePrinter()
+        p._not_c = set()
+
+        assert p._print_Indexed(x) == 'x[j]'
+        assert p._print_Indexed(A) == 'A[%s]' % (m*i+j)
+        assert p._print_Indexed(B) == 'B[%s]' % (i*o*m+j*o+k)
+        assert p._not_c == set()
+
 
 
 def test_ccode_Indexed_without_looking_for_contraction():
@@ -285,8 +297,7 @@ def test_ccode_loops_matrix_vector():
         '   }\n'
         '}'
     )
-    c = ccode(A[i, j]*x[j], assign_to=y[i])
-    assert c == s
+    assert ccode(A[i, j]*x[j], assign_to=y[i]) == s
 
 
 def test_dummy_loops():
@@ -300,8 +311,8 @@ def test_dummy_loops():
         '   y[i_%(icount)i] = x[i_%(icount)i];\n'
         '}'
     ) % {'icount': i.label.dummy_index, 'mcount': m.dummy_index}
-    code = ccode(x[i], assign_to=y[i])
-    assert code == expected
+
+    assert ccode(x[i], assign_to=y[i]) == expected
 
 
 def test_ccode_loops_add():
@@ -325,8 +336,7 @@ def test_ccode_loops_add():
         '   }\n'
         '}'
     )
-    c = ccode(A[i, j]*x[j] + x[i] + z[i], assign_to=y[i])
-    assert c == s
+    assert ccode(A[i, j]*x[j] + x[i] + z[i], assign_to=y[i]) == s
 
 
 def test_ccode_loops_multiple_contractions():
@@ -355,8 +365,7 @@ def test_ccode_loops_multiple_contractions():
         '   }\n'
         '}'
     )
-    c = ccode(b[j, k, l]*a[i, j, k, l], assign_to=y[i])
-    assert c == s
+    assert ccode(b[j, k, l]*a[i, j, k, l], assign_to=y[i]) == s
 
 
 def test_ccode_loops_addfactor():
@@ -386,8 +395,7 @@ def test_ccode_loops_addfactor():
         '   }\n'
         '}'
     )
-    c = ccode((a[i, j, k, l] + b[i, j, k, l])*c[j, k, l], assign_to=y[i])
-    assert c == s
+    assert ccode((a[i, j, k, l] + b[i, j, k, l])*c[j, k, l], assign_to=y[i]) == s
 
 
 def test_ccode_loops_multiple_terms():
@@ -430,8 +438,7 @@ def test_ccode_loops_multiple_terms():
         '   }\n'
         '}\n'
     )
-    c = ccode(
-        b[j]*a[i, j] + b[k]*a[i, k] + b[j]*b[k]*c[i, j, k], assign_to=y[i])
+    c = ccode(b[j]*a[i, j] + b[k]*a[i, k] + b[j]*b[k]*c[i, j, k], assign_to=y[i])
     assert (c == s0 + s1 + s2 + s3[:-1] or
             c == s0 + s1 + s3 + s2[:-1] or
             c == s0 + s2 + s1 + s3[:-1] or
@@ -486,30 +493,22 @@ def test_Matrix_printing():
 
 
 def test_ccode_reserved_words():
-
     x, y = symbols('x, if')
-
+    with raises(ValueError):
+        ccode(y**2, error_on_reserved=True, standard='C99')
     assert ccode(y**2) == 'pow(if_, 2)'
     assert ccode(x * y**2, dereference=[y]) == 'pow((*if_), 2)*x'
-
-    expected = 'pow(if_unreserved, 2)'
-    assert ccode(y**2, reserved_word_suffix='_unreserved') == expected
-
-    with raises(ValueError):
-        ccode(y**2, error_on_reserved=True)
+    assert ccode(y**2, reserved_word_suffix='_unreserved') == 'pow(if_unreserved, 2)'
 
 
 def test_ccode_sign():
-
-    expr = sign(x) * y
-    assert ccode(expr) == 'y*(((x) > 0) - ((x) < 0))'
-    assert ccode(expr, 'z') == 'z = y*(((x) > 0) - ((x) < 0));'
-
-    assert ccode(sign(2 * x + x**2) * x + x**2) == \
-        'pow(x, 2) + x*(((pow(x, 2) + 2*x) > 0) - ((pow(x, 2) + 2*x) < 0))'
-
-    expr = sign(cos(x))
-    assert ccode(expr) == '(((cos(x)) > 0) - ((cos(x)) < 0))'
+    expr1, ref1 = sign(x) * y, 'y*(((x) > 0) - ((x) < 0))'
+    expr2, ref2 = sign(cos(x)), '(((cos(x)) > 0) - ((cos(x)) < 0))'
+    expr3, ref3 = sign(2 * x + x**2) * x + x**2, 'pow(x, 2) + x*(((pow(x, 2) + 2*x) > 0) - ((pow(x, 2) + 2*x) < 0))'
+    assert ccode(expr1) == ref1
+    assert ccode(expr1, 'z') == 'z = %s;' % ref1
+    assert ccode(expr2) == ref2
+    assert ccode(expr3) == ref3
 
 def test_ccode_Assignment():
     assert ccode(Assignment(x, y + z)) == 'x = y + z;'
@@ -518,7 +517,61 @@ def test_ccode_Assignment():
 
 def test_ccode_For():
     f = For(x, Range(0, 10, 2), [aug_assign(y, '*', x)])
-    sol = ccode(f)
-    assert sol == ("for (x = 0; x < 10; x += 2) {\n"
-                   "   y *= x;\n"
-                   "}")
+    assert ccode(f) == ("for (x = 0; x < 10; x += 2) {\n"
+                        "   y *= x;\n"
+                        "}")
+
+def test_ccode_Max_Min():
+    assert ccode(Max(x, 0), standard='C89') == '((0 > x) ? 0 : x)'
+    assert ccode(Max(x, 0), standard='C99') == 'fmax(0, x)'
+    assert ccode(Min(x, 0, sqrt(x)), standard='c89') == (
+        '((0 < ((x < sqrt(x)) ? x : sqrt(x))) ? 0 : ((x < sqrt(x)) ? x : sqrt(x)))'
+    )
+
+def test_ccode_standard():
+    assert ccode(expm1(x), standard='c99') == 'expm1(x)'
+    assert ccode(nan, standard='c99') == 'NAN'
+    assert ccode(float('nan'), standard='c99') == 'NAN'
+
+
+def test_CCodePrinter():
+    with warnings.catch_warnings():
+        warnings.filterwarnings("error", category=SymPyDeprecationWarning)
+        with raises(SymPyDeprecationWarning):
+            CCodePrinter()
+    with warnings.catch_warnings():
+        warnings.filterwarnings("ignore", category=SymPyDeprecationWarning)
+        assert CCodePrinter().language == 'C'
+
+
+def test_C89CodePrinter():
+    c89printer = C89CodePrinter()
+    assert c89printer.language == 'C'
+    assert c89printer.standard == 'C89'
+    assert 'void' in c89printer.reserved_words
+    assert 'template' not in c89printer.reserved_words
+
+
+def test_C99CodePrinter():
+    assert C99CodePrinter().doprint(expm1(x)) == 'expm1(x)'
+    assert C99CodePrinter().doprint(log1p(x)) == 'log1p(x)'
+    assert C99CodePrinter().doprint(exp2(x)) == 'exp2(x)'
+    assert C99CodePrinter().doprint(log2(x)) == 'log2(x)'
+    assert C99CodePrinter().doprint(fma(x, y, -z)) == 'fma(x, y, -z)'
+    assert C99CodePrinter().doprint(log10(x)) == 'log10(x)'
+    assert C99CodePrinter().doprint(Cbrt(x)) == 'cbrt(x)'  # note Cbrt due to cbrt already taken.
+    assert C99CodePrinter().doprint(hypot(x, y)) == 'hypot(x, y)'
+    assert C99CodePrinter().doprint(loggamma(x)) == 'lgamma(x)'
+    assert C99CodePrinter().doprint(Max(x, 3, x**2)) == 'fmax(3, fmax(x, pow(x, 2)))'
+    assert C99CodePrinter().doprint(Min(x, 3)) == 'fmin(3, x)'
+    c99printer = C99CodePrinter()
+    assert c99printer.language == 'C'
+    assert c99printer.standard == 'C99'
+    assert 'restrict' in c99printer.reserved_words
+    assert 'using' not in c99printer.reserved_words
+
+
+def test_get_math_macros():
+    macros = get_math_macros()
+    assert macros[exp(1)] == 'M_E'
+    assert macros[1/Sqrt(2)] == 'M_SQRT1_2'
diff --git a/sympy/printing/tests/test_cxxcode.py b/sympy/printing/tests/test_cxxcode.py
new file mode 100644
index 0000000000..9813066f8d
--- /dev/null
+++ b/sympy/printing/tests/test_cxxcode.py
@@ -0,0 +1,56 @@
+from sympy import symbols
+from sympy.functions import beta, Ei, zeta, Max, Min, sqrt, exp
+from sympy.printing.cxxcode import CXX98CodePrinter, CXX11CodePrinter, CXX17CodePrinter, cxxcode
+from sympy.codegen.cfunctions import log1p
+
+x, y = symbols('x y')
+
+
+def test_CXX98CodePrinter():
+    assert CXX98CodePrinter().doprint(Max(x, 3)) in ('std::max(x, 3)', 'std::max(3, x)')
+    assert CXX98CodePrinter().doprint(Min(x, 3, sqrt(x))) == 'std::min(3, std::min(x, std::sqrt(x)))'
+    cxx98printer = CXX98CodePrinter()
+    assert cxx98printer.language == 'C++'
+    assert cxx98printer.standard == 'C++98'
+    assert 'template' in cxx98printer.reserved_words
+    assert 'alignas' not in cxx98printer.reserved_words
+
+
+def test_CXX11CodePrinter():
+    assert CXX11CodePrinter().doprint(log1p(x)) == 'std::log1p(x)'
+
+    cxx11printer = CXX11CodePrinter()
+    assert cxx11printer.language == 'C++'
+    assert cxx11printer.standard == 'C++11'
+    assert 'operator' in cxx11printer.reserved_words
+    assert 'noexcept' in cxx11printer.reserved_words
+    assert 'concept' not in cxx11printer.reserved_words
+
+
+def test_subclass_print_method():
+    class MyPrinter(CXX11CodePrinter):
+        def _print_log1p(self, expr):
+            return 'my_library::log1p(%s)' % ', '.join(map(self._print, expr.args))
+
+    assert MyPrinter().doprint(log1p(x)) == 'my_library::log1p(x)'
+
+
+def test_subclass_print_method__ns():
+    class MyPrinter(CXX11CodePrinter):
+        _ns = 'my_library::'
+
+    p = CXX11CodePrinter()
+    myp = MyPrinter()
+
+    assert p.doprint(log1p(x)) == 'std::log1p(x)'
+    assert myp.doprint(log1p(x)) == 'my_library::log1p(x)'
+
+
+def test_CXX17CodePrinter():
+    assert CXX17CodePrinter().doprint(beta(x, y)) == 'std::beta(x, y)'
+    assert CXX17CodePrinter().doprint(Ei(x)) == 'std::expint(x)'
+    assert CXX17CodePrinter().doprint(zeta(x)) == 'std::riemann_zeta(x)'
+
+
+def test_cxxcode():
+    assert sorted(cxxcode(sqrt(x)*.5).split('*')) == sorted(['0.5', 'std::sqrt(x)'])
diff --git a/sympy/printing/tests/test_numpy.py b/sympy/printing/tests/test_numpy.py
index a5ddc4f35c..3f7a68456e 100644
--- a/sympy/printing/tests/test_numpy.py
+++ b/sympy/printing/tests/test_numpy.py
@@ -1,5 +1,6 @@
-from sympy import Piecewise, lambdify, Equality, Unequality, Sum, Mod
+from sympy import Piecewise, lambdify, Equality, Unequality, Sum, Mod, cbrt, sqrt
 from sympy.abc import x, i, j, a, b, c, d
+from sympy.codegen.cfunctions import log1p, expm1, hypot, log10, exp2, log2, Cbrt, Sqrt
 from sympy.printing.lambdarepr import NumPyPrinter
 
 from sympy.utilities.pytest import skip
@@ -109,3 +110,53 @@ def test_mod():
     a_ = np.array([2, 3, 4, 5])
     b_ = np.array([2, 3, 4, 5])
     assert np.array_equal(f(a_, b_), [0, 0, 0, 0])
+
+
+def test_expm1():
+    if not np:
+        skip("NumPy not installed")
+
+    f = lambdify((a,), expm1(a), 'numpy')
+    assert abs(f(1e-10) - 1e-10 - 5e-21) < 1e-22
+
+
+def test_log1p():
+    if not np:
+        skip("NumPy not installed")
+
+    f = lambdify((a,), log1p(a), 'numpy')
+    assert abs(f(1e-99) - 1e-99) < 1e-100
+
+def test_hypot():
+    if not np:
+        skip("NumPy not installed")
+    assert abs(lambdify((a, b), hypot(a, b), 'numpy')(3, 4) - 5) < 1e-16
+
+def test_log10():
+    if not np:
+        skip("NumPy not installed")
+    assert abs(lambdify((a,), log10(a), 'numpy')(100) - 2) < 1e-16
+
+
+def test_exp2():
+    if not np:
+        skip("NumPy not installed")
+    assert abs(lambdify((a,), exp2(a), 'numpy')(5) - 32) < 1e-16
+
+
+def test_log2():
+    if not np:
+        skip("NumPy not installed")
+    assert abs(lambdify((a,), log2(a), 'numpy')(256) - 8) < 1e-16
+
+
+def test_Sqrt():
+    if not np:
+        skip("NumPy not installed")
+    assert abs(lambdify((a,), Sqrt(a), 'numpy')(4) - 2) < 1e-16
+
+
+def test_sqrt():
+    if not np:
+        skip("NumPy not installed")
+    assert abs(lambdify((a,), sqrt(a), 'numpy')(4) - 2) < 1e-16
diff --git a/sympy/utilities/tests/test_autowrap.py b/sympy/utilities/tests/test_autowrap.py
index 692eba8f4b..6b253a05fc 100644
--- a/sympy/utilities/tests/test_autowrap.py
+++ b/sympy/utilities/tests/test_autowrap.py
@@ -4,14 +4,17 @@
 import os
 import tempfile
 import shutil
+import warnings
 
-from sympy.utilities.autowrap import (autowrap, binary_function,
-            CythonCodeWrapper, ufuncify, UfuncifyCodeWrapper, CodeWrapper)
-from sympy.utilities.codegen import (CCodeGen, CodeGenArgumentListError,
-                                     make_routine)
-from sympy.utilities.pytest import raises
 from sympy.core import symbols, Eq
 from sympy.core.compatibility import StringIO
+from sympy.utilities.exceptions import SymPyDeprecationWarning
+from sympy.utilities.pytest import raises
+from sympy.utilities.autowrap import (autowrap, binary_function,
+            CythonCodeWrapper, ufuncify, UfuncifyCodeWrapper, CodeWrapper)
+from sympy.utilities.codegen import (
+    CCodeGen, C99CodeGen, CodeGenArgumentListError, make_routine
+)
 
 
 def get_string(dump_fn, routines, prefix="file", **kwargs):
@@ -33,8 +36,11 @@ def test_cython_wrapper_scalar_function():
     x, y, z = symbols('x,y,z')
     expr = (x + y)*z
     routine = make_routine("test", expr)
-    code_gen = CythonCodeWrapper(CCodeGen())
-    source = get_string(code_gen.dump_pyx, [routine])
+    with warnings.catch_warnings():
+        warnings.filterwarnings('ignore', category=SymPyDeprecationWarning)
+        code_gen = CythonCodeWrapper(CCodeGen())
+        source = get_string(code_gen.dump_pyx, [routine])
+
     expected = (
         "cdef extern from 'file.h':\n"
         "    double test(double x, double y, double z)\n"
@@ -48,7 +54,7 @@ def test_cython_wrapper_scalar_function():
 def test_cython_wrapper_outarg():
     from sympy import Equality
     x, y, z = symbols('x,y,z')
-    code_gen = CythonCodeWrapper(CCodeGen())
+    code_gen = CythonCodeWrapper(C99CodeGen())
 
     routine = make_routine("test", Equality(z, x + y))
     source = get_string(code_gen.dump_pyx, [routine])
@@ -67,7 +73,7 @@ def test_cython_wrapper_outarg():
 def test_cython_wrapper_inoutarg():
     from sympy import Equality
     x, y, z = symbols('x,y,z')
-    code_gen = CythonCodeWrapper(CCodeGen())
+    code_gen = CythonCodeWrapper(C99CodeGen())
     routine = make_routine("test", Equality(z, x + y + z))
     source = get_string(code_gen.dump_pyx, [routine])
     expected = (
@@ -142,7 +148,7 @@ def test_binary_function():
 
 def test_ufuncify_source():
     x, y, z = symbols('x,y,z')
-    code_wrapper = UfuncifyCodeWrapper(CCodeGen("ufuncify"))
+    code_wrapper = UfuncifyCodeWrapper(C99CodeGen("ufuncify"))
     CodeWrapper._module_counter = 0
     routine = make_routine("test", x + y + z)
     source = get_string(code_wrapper.dump_c, [routine])
@@ -237,7 +243,7 @@ def test_ufuncify_source_multioutput():
     x, y, z = symbols('x,y,z')
     var_symbols = (x, y, z)
     expr = x + y**3 + 10*z**2
-    code_wrapper = UfuncifyCodeWrapper(CCodeGen("ufuncify"))
+    code_wrapper = UfuncifyCodeWrapper(C99CodeGen("ufuncify"))
     CodeWrapper._module_counter = 0
     routines = [make_routine("func{}".format(i), expr.diff(var_symbols[i]), var_symbols) for i in range(len(var_symbols))]
     source = get_string(code_wrapper.dump_c, routines, funcname='multitest')
diff --git a/sympy/utilities/tests/test_codegen.py b/sympy/utilities/tests/test_codegen.py
index c8314d412b..93783c083a 100644
--- a/sympy/utilities/tests/test_codegen.py
+++ b/sympy/utilities/tests/test_codegen.py
@@ -1,11 +1,14 @@
+import warnings
 from sympy.core import symbols, Eq, pi, Catalan, Lambda, Dummy
 from sympy.core.compatibility import StringIO
 from sympy import erf, Integral
 from sympy import Equality
 from sympy.matrices import Matrix, MatrixSymbol
-from sympy.utilities.codegen import (codegen, make_routine, CCodeGen,
-            InputArgument, CodeGenError, FCodeGen, CodeGenArgumentListError,
-            OutputArgument, InOutArgument)
+from sympy.utilities.codegen import (
+    codegen, make_routine, CCodeGen, C89CodeGen, C99CodeGen, InputArgument,
+    CodeGenError, FCodeGen, CodeGenArgumentListError, OutputArgument,
+    InOutArgument)
+from sympy.utilities.exceptions import SymPyDeprecationWarning
 from sympy.utilities.pytest import raises
 from sympy.utilities.lambdify import implemented_function
 
@@ -56,13 +59,15 @@ def test_Routine_argument_order():
 
 
 def test_empty_c_code():
-    code_gen = CCodeGen()
-    source = get_string(code_gen.dump_c, [])
-    assert source == "#include \"file.h\"\n#include <math.h>\n"
+    code_gen = C89CodeGen()
+    with warnings.catch_warnings():
+        warnings.filterwarnings("ignore", category=SymPyDeprecationWarning)
+        source = get_string(code_gen.dump_c, [])
+        assert source == "#include \"file.h\"\n#include <math.h>\n"
 
 
 def test_empty_c_code_with_comment():
-    code_gen = CCodeGen()
+    code_gen = C89CodeGen()
     source = get_string(code_gen.dump_c, [], header=True)
     assert source[:82] == (
         "/******************************************************************************\n *"
@@ -80,7 +85,7 @@ def test_empty_c_code_with_comment():
 
 
 def test_empty_c_header():
-    code_gen = CCodeGen()
+    code_gen = C99CodeGen()
     source = get_string(code_gen.dump_h, [])
     assert source == "#ifndef PROJECT__FILE__H\n#define PROJECT__FILE__H\n#endif\n"
 
@@ -89,7 +94,7 @@ def test_simple_c_code():
     x, y, z = symbols('x,y,z')
     expr = (x + y)*z
     routine = make_routine("test", expr)
-    code_gen = CCodeGen()
+    code_gen = C89CodeGen()
     source = get_string(code_gen.dump_c, [routine])
     expected = (
         "#include \"file.h\"\n"
@@ -107,7 +112,7 @@ def test_c_code_reserved_words():
     x, y, z = symbols('if, typedef, while')
     expr = (x + y) * z
     routine = make_routine("test", expr)
-    code_gen = CCodeGen()
+    code_gen = C99CodeGen()
     source = get_string(code_gen.dump_c, [routine])
     expected = (
         "#include \"file.h\"\n"
@@ -123,7 +128,7 @@ def test_c_code_reserved_words():
 
 def test_numbersymbol_c_code():
     routine = make_routine("test", pi**Catalan)
-    code_gen = CCodeGen()
+    code_gen = C89CodeGen()
     source = get_string(code_gen.dump_c, [routine])
     expected = (
         "#include \"file.h\"\n"
@@ -142,7 +147,7 @@ def test_c_code_argument_order():
     x, y, z = symbols('x,y,z')
     expr = x + y
     routine = make_routine("test", expr, argument_sequence=[z, x, y])
-    code_gen = CCodeGen()
+    code_gen = C89CodeGen()
     source = get_string(code_gen.dump_c, [routine])
     expected = (
         "#include \"file.h\"\n"
@@ -160,7 +165,7 @@ def test_simple_c_header():
     x, y, z = symbols('x,y,z')
     expr = (x + y)*z
     routine = make_routine("test", expr)
-    code_gen = CCodeGen()
+    code_gen = C89CodeGen()
     source = get_string(code_gen.dump_h, [routine])
     expected = (
         "#ifndef PROJECT__FILE__H\n"
@@ -174,7 +179,6 @@ def test_simple_c_header():
 def test_simple_c_codegen():
     x, y, z = symbols('x,y,z')
     expr = (x + y)*z
-    result = codegen(("test", expr), "C", "file", header=False, empty=False)
     expected = [
         ("file.c",
         "#include \"file.h\"\n"
@@ -190,7 +194,10 @@ def test_simple_c_codegen():
         "double test(double x, double y, double z);\n"
         "#endif\n")
     ]
-    assert result == expected
+    with warnings.catch_warnings():
+        warnings.filterwarnings("ignore", category=SymPyDeprecationWarning)
+        result = codegen(("test", expr), "C", "file", header=False, empty=False)
+        assert result == expected
 
 
 def test_multiple_results_c():
@@ -201,7 +208,7 @@ def test_multiple_results_c():
         "test",
         [expr1, expr2]
     )
-    code_gen = CCodeGen()
+    code_gen = C99CodeGen()
     raises(CodeGenError, lambda: get_string(code_gen.dump_h, [routine]))
 
 
@@ -231,7 +238,7 @@ def test_ansi_math1_codegen():
         ("test_tan", tan(x)),
         ("test_tanh", tanh(x)),
     ]
-    result = codegen(name_expr, "C", "file", header=False, empty=False)
+    result = codegen(name_expr, "C89", "file", header=False, empty=False)
     assert result[0][0] == "file.c"
     assert result[0][1] == (
         '#include "file.h"\n#include <math.h>\n'
@@ -273,7 +280,7 @@ def test_ansi_math2_codegen():
         ("test_atan2", atan2(x, y)),
         ("test_pow", x**y),
     ]
-    result = codegen(name_expr, "C", "file", header=False, empty=False)
+    result = codegen(name_expr, "C89", "file", header=False, empty=False)
     assert result[0][0] == "file.c"
     assert result[0][1] == (
         '#include "file.h"\n#include <math.h>\n'
@@ -296,7 +303,7 @@ def test_complicated_codegen():
         ("test1", ((sin(x) + cos(y) + tan(z))**7).expand()),
         ("test2", cos(cos(cos(cos(cos(cos(cos(cos(x + y + z))))))))),
     ]
-    result = codegen(name_expr, "C", "file", header=False, empty=False)
+    result = codegen(name_expr, "C89", "file", header=False, empty=False)
     assert result[0][0] == "file.c"
     assert result[0][1] == (
         '#include "file.h"\n#include <math.h>\n'
@@ -368,7 +375,7 @@ def test_loops_c():
     j = Idx('j', n)
 
     (f1, code), (f2, interface) = codegen(
-        ('matrix_vector', Eq(y[i], A[i, j]*x[j])), "C", "file", header=False, empty=False)
+        ('matrix_vector', Eq(y[i], A[i, j]*x[j])), "C99", "file", header=False, empty=False)
 
     assert f1 == 'file.c'
     expected = (
@@ -415,10 +422,12 @@ def test_dummy_loops_c():
         '}\n'
     ) % {'ino': i.label.dummy_index, 'mno': m.dummy_index}
     r = make_routine('test_dummies', Eq(y[i], x[i]))
-    c = CCodeGen()
-    code = get_string(c.dump_c, [r])
+    c89 = C89CodeGen()
+    c99 = C99CodeGen()
+    code = get_string(c99.dump_c, [r])
     assert code == expected
-
+    with raises(NotImplementedError):
+        get_string(c89.dump_c, [r])
 
 def test_partial_loops_c():
     # check that loop boundaries are determined by Idx, and array strides
@@ -433,7 +442,7 @@ def test_partial_loops_c():
     j = Idx('j', n)          # dimension n corresponds to bounds (0, n - 1)
 
     (f1, code), (f2, interface) = codegen(
-        ('matrix_vector', Eq(y[i], A[i, j]*x[j])), "C", "file", header=False, empty=False)
+        ('matrix_vector', Eq(y[i], A[i, j]*x[j])), "C99", "file", header=False, empty=False)
 
     assert f1 == 'file.c'
     expected = (
@@ -468,7 +477,7 @@ def test_output_arg_c():
     from sympy import sin, cos, Equality
     x, y, z = symbols("x,y,z")
     r = make_routine("foo", [Equality(y, sin(x)), cos(x)])
-    c = CCodeGen()
+    c = C89CodeGen()
     result = c.write([r], "test", header=False, empty=False)
     assert result[0][0] == "test.c"
     expected = (
@@ -488,7 +497,7 @@ def test_output_arg_c_reserved_words():
     from sympy import sin, cos, Equality
     x, y, z = symbols("if, while, z")
     r = make_routine("foo", [Equality(y, sin(x)), cos(x)])
-    c = CCodeGen()
+    c = C89CodeGen()
     result = c.write([r], "test", header=False, empty=False)
     assert result[0][0] == "test.c"
     expected = (
@@ -512,9 +521,6 @@ def test_ccode_results_named_ordered():
     expr2 = Equality(C, (x + y)*z)
     expr3 = Equality(B, 2*x)
     name_expr = ("test", [expr1, expr2, expr3])
-    result = codegen(name_expr, "c", "test", header=False, empty=False,
-                     argument_sequence=(x, C, z, y, A, B))
-    source = result[0][1]
     expected = (
         '#include "test.h"\n'
         '#include <math.h>\n'
@@ -526,7 +532,13 @@ def test_ccode_results_named_ordered():
         '   (*B) = 2*x;\n'
         '}\n'
     )
-    assert source == expected
+    with warnings.catch_warnings():
+        warnings.filterwarnings("ignore", category=SymPyDeprecationWarning)
+
+        result = codegen(name_expr, "c", "test", header=False, empty=False,
+                         argument_sequence=(x, C, z, y, A, B))
+        source = result[0][1]
+        assert source == expected
 
 
 def test_ccode_matrixsymbol_slice():
@@ -537,7 +549,7 @@ def test_ccode_matrixsymbol_slice():
     name_expr = ("test", [Equality(B, A[0, :]),
                           Equality(C, A[1, :]),
                           Equality(D, A[:, 2])])
-    result = codegen(name_expr, "c", "test", header=False, empty=False)
+    result = codegen(name_expr, "c99", "test", header=False, empty=False)
     source = result[0][1]
     expected = (
         '#include "test.h"\n'
@@ -1284,8 +1296,8 @@ def test_c_fortran_omit_routine_name():
     assert result[0][1] == expresult[0][1]
 
     name_expr = ("foo", Matrix([[x, y], [x+y, x-y]]))
-    result = codegen(name_expr, "C", header=False, empty=False)
-    expresult = codegen(name_expr, "C", "foo", header=False, empty=False)
+    result = codegen(name_expr, "C89", header=False, empty=False)
+    expresult = codegen(name_expr, "C89", "foo", header=False, empty=False)
     assert result[0][1] == expresult[0][1]
 
 
@@ -1414,9 +1426,6 @@ def test_global_vars():
         )
     assert source == expected
 
-    result = codegen(('f', x*y+z), "C", header=False, empty=False,
-                     global_vars=(z, t))
-    source = result[0][1]
     expected = (
         '#include "f.h"\n'
         '#include <math.h>\n'
@@ -1426,4 +1435,9 @@ def test_global_vars():
         '   return f_result;\n'
         '}\n'
     )
-    assert source == expected
+    with warnings.catch_warnings():
+        warnings.filterwarnings("ignore", category=SymPyDeprecationWarning)
+        result = codegen(('f', x*y+z), "C", header=False, empty=False,
+                         global_vars=(z, t))
+        source = result[0][1]
+        assert source == expected