diff --git a/pub/lib/fassign.cpp b/pub/lib/fassign.cpp
index 9e3c32dd76741a9bd407f475a80dee45ef94404b..c2ddc56ace221e8575951d45cc40b2527b25e3c8 100644
--- a/pub/lib/fassign.cpp
+++ b/pub/lib/fassign.cpp
@@ -43,18 +43,18 @@ void func_undef (string key)
 
 void fassign_initialize()
 {
-
     auto G = SFuncRegistry::get_instance();
-
-    G->register_fct_meta ( "=",   2, "a=b     [assignment]", 14 );
-    G->register_fct_i_si ( "=",  func_assign );
-    G->register_fct_d_sd ( "=",  func_assign );
-    G->register_fct_e_se ( "=",  func_assign );
-    G->register_fct_s_ss ( "=",  func_assign );
-
-    G->register_fct_meta ( "defined", 1, "(s): 1 if there is a variable s" );
-    G->register_fct_i_s  ( "defined",  func_defined );
-    G->register_fct_meta ( "undef", 1, "(s): undefine variable s, return 1 upon success" );
-    G->register_fct_0_s  ( "undef",  func_undef );
+    CFuncMetadata m;
+
+    m = { "=",   2, "a=b     [assignment]", 14 };
+    G->register_fct_i_si ( m,  func_assign );
+    G->register_fct_d_sd ( m,  func_assign );
+    G->register_fct_e_se ( m,  func_assign );
+    G->register_fct_s_ss ( m,  func_assign );
+
+    m = { "defined", 1, "(s): 1 if there is a variable s" };
+    G->register_fct_i_s  ( m,  func_defined );
+    m = { "undef", 1, "(s): undefine variable s, return 1 upon success" };
+    G->register_fct_0_s  ( m,  func_undef );
 
 }
diff --git a/pub/lib/fbase.cpp b/pub/lib/fbase.cpp
index 3d4bd8274ec52de8cd190421a3924a055d68f905..dca1a3c67583b67fa880754f47fc1f0c4ab73e6e 100644
--- a/pub/lib/fbase.cpp
+++ b/pub/lib/fbase.cpp
@@ -399,243 +399,243 @@ double func_ornuhl( double _w, double _a, double _b )
 
 void fbase_initialize()
 {
-
     auto G = SFuncRegistry::get_instance();
+    CFuncMetadata m;
 
     // operators by precedence (which should agree with xax_yacc.ypp):
-    G->register_fct_meta ( "+-",  2, "a+-da   [set error]", 1 );
-    G->register_fct_e_dd ( "+-", func_pm );
-    G->register_fct_meta ( "^",   2, "a^b     [exponentiation]", 2 );
-    G->register_fct_d_dd ( "^", func_pow );
-    G->register_fct_e_ee ( "^", func_pow );
-    G->register_fct_meta ( "!",   1, "!a      [negation]", 3 );
-    G->register_fct_i_i  ( "!", func_not );
-    G->register_fct_i_d  ( "!", func_not );
-    G->register_fct_meta ( "neg", 1, "-a      [negative value]", 4 );
-    G->register_fct_i_i  ( "neg", func_neg );
-    G->register_fct_d_d  ( "neg", func_neg );
-    G->register_fct_e_e  ( "neg", func_neg );
-    G->register_fct_meta ( "/",   2, "a/b     [quotient]", 5 );
-    G->register_fct_d_dd ( "/", func_div );
-    G->register_fct_e_ee ( "/", func_div );
-    G->register_fct_meta ( "//",  2, "i//j    [integer quotient]", 5 );
-    G->register_fct_i_ii ( "//", func_idiv );
-    G->register_fct_i_di ( "//", func_idiv );
-    G->register_fct_meta ( "%",   2, "i%j     [remainder]", 5 );
-    G->register_fct_i_ii ( "%", func_mod );
-    G->register_fct_d_dd ( "%", func_mod );
-    G->register_fct_meta ( "*",   2, "a*b     [product]", 6 );
-    G->register_fct_i_ii ( "*", func_mul );
-    G->register_fct_d_dd ( "*", func_mul );
-    G->register_fct_e_ee ( "*", func_mul );
-    G->register_fct_meta ( "+",   2, "a+b     [sum]", 7 );
-    G->register_fct_i_ii ( "+", func_add );
-    G->register_fct_d_dd ( "+", func_add );
-    G->register_fct_e_ee ( "+", func_add );
-    G->register_fct_meta ( "-",   2, "a-b     [difference]", 7 );
-    G->register_fct_i_ii ( "-", func_sub );
-    G->register_fct_d_dd ( "-", func_sub );
-    G->register_fct_e_ee ( "-", func_sub );
-    G->register_fct_meta ( ">",   2, "a>b     [greater]", 8 );
-    G->register_fct_i_ii ( ">", func_gt );
-    G->register_fct_i_dd ( ">", func_gt );
-    G->register_fct_meta ( "<",   2, "a<b     [less]", 8 );
-    G->register_fct_i_ii ( "<", func_lt );
-    G->register_fct_i_dd ( "<", func_lt );
-    G->register_fct_meta ( ">=",  2, "a>=b    [greater or equal]", 8 );
-    G->register_fct_i_ii ( ">=", func_ge );
-    G->register_fct_i_dd ( ">=", func_ge );
-    G->register_fct_meta ( "<=",  2, "a<=b    [less or equal]", 8 );
-    G->register_fct_i_ii ( "<=", func_le );
-    G->register_fct_i_dd ( "<=", func_le );
-    G->register_fct_meta ( "==",  2, "a==b    [equality]", 9 );
-    G->register_fct_i_ii ( "==", func_eq );
-    G->register_fct_i_dd ( "==", func_eq );
-    G->register_fct_meta ( "!=",  2, "a!=b    [unequality]", 9 );
-    G->register_fct_i_ii ( "!=", func_ne );
-    G->register_fct_i_dd ( "!=", func_ne );
-    G->register_fct_meta ( "xor", 2, "a^b     [exclusive or]", 10 );
-    G->register_fct_i_ii ( "xor", func_xor );
-    G->register_fct_i_dd ( "xor", func_xor );
-    G->register_fct_meta ( "&&",  2, "a&&b    [and]", 11 );
-    G->register_fct_i_ii ( "&&", func_and );
-    G->register_fct_i_dd ( "&&", func_and );
-    G->register_fct_meta ( "||",  2, "a||b    [or]", 11 );
-    G->register_fct_i_ii ( "||", func_or );
-    G->register_fct_i_dd ( "||", func_or );
-    G->register_fct_meta ( "?:",  2, "a?b:c   [if a then b else c]", 13 );
-    G->register_fct_i_iii( "?:", func_cond );
-    G->register_fct_d_ddd( "?:", func_cond );
-    G->register_fct_e_eee( "?:", func_cond );
+    m = { "+-",  2, "a+-da   [set error]", 1  };
+    G->register_fct_e_dd ( m, func_pm );
+    m = { "^",   2, "a^b     [exponentiation]", 2 };
+    G->register_fct_d_dd ( m, func_pow );
+    G->register_fct_e_ee ( m, func_pow );
+    m = { "!",   1, "!a      [negation]", 3 };
+    G->register_fct_i_i  ( m, func_not );
+    G->register_fct_i_d  ( m, func_not );
+    m = { "neg", 1, "-a      [negative value]", 4 };
+    G->register_fct_i_i  ( m, func_neg );
+    G->register_fct_d_d  ( m, func_neg );
+    G->register_fct_e_e  ( m, func_neg );
+    m = { "/",   2, "a/b     [quotient]", 5 };
+    G->register_fct_d_dd ( m, func_div );
+    G->register_fct_e_ee ( m, func_div );
+    m = { "//",  2, "i//j    [integer quotient]", 5 };
+    G->register_fct_i_ii ( m, func_idiv );
+    G->register_fct_i_di ( m, func_idiv );
+    m = { "%",   2, "i%j     [remainder]", 5 };
+    G->register_fct_i_ii ( m, func_mod );
+    G->register_fct_d_dd ( m, func_mod );
+    m = { "*",   2, "a*b     [product]", 6 };
+    G->register_fct_i_ii ( m, func_mul );
+    G->register_fct_d_dd ( m, func_mul );
+    G->register_fct_e_ee ( m, func_mul );
+    m = { "+",   2, "a+b     [sum]", 7 };
+    G->register_fct_i_ii ( m, func_add );
+    G->register_fct_d_dd ( m, func_add );
+    G->register_fct_e_ee ( m, func_add );
+    m = { "-",   2, "a-b     [difference]", 7 };
+    G->register_fct_i_ii ( m, func_sub );
+    G->register_fct_d_dd ( m, func_sub );
+    G->register_fct_e_ee ( m, func_sub );
+    m = { ">",   2, "a>b     [greater]", 8 };
+    G->register_fct_i_ii ( m, func_gt );
+    G->register_fct_i_dd ( m, func_gt );
+    m = { "<",   2, "a<b     [less]", 8 };
+    G->register_fct_i_ii ( m, func_lt );
+    G->register_fct_i_dd ( m, func_lt );
+    m = { ">=",  2, "a>=b    [greater or equal]", 8 };
+    G->register_fct_i_ii ( m, func_ge );
+    G->register_fct_i_dd ( m, func_ge );
+    m = { "<=",  2, "a<=b    [less or equal]", 8 };
+    G->register_fct_i_ii ( m, func_le );
+    G->register_fct_i_dd ( m, func_le );
+    m = { "==",  2, "a==b    [equality]", 9 };
+    G->register_fct_i_ii ( m, func_eq );
+    G->register_fct_i_dd ( m, func_eq );
+    m = { "!=",  2, "a!=b    [unequality]", 9 };
+    G->register_fct_i_ii ( m, func_ne );
+    G->register_fct_i_dd ( m, func_ne );
+    m = { "xor", 2, "a^b     [exclusive or]", 10 };
+    G->register_fct_i_ii ( m, func_xor );
+    G->register_fct_i_dd ( m, func_xor );
+    m = { "&&",  2, "a&&b    [and]", 11 };
+    G->register_fct_i_ii ( m, func_and );
+    G->register_fct_i_dd ( m, func_and );
+    m = { "||",  2, "a||b    [or]", 11 };
+    G->register_fct_i_ii ( m, func_or );
+    G->register_fct_i_dd ( m, func_or );
+    m = { "?:",  2, "a?b:c   [if a then b else c]", 13 };
+    G->register_fct_i_iii( m, func_cond );
+    G->register_fct_d_ddd( m, func_cond );
+    G->register_fct_e_eee( m, func_cond );
 
 
     // f( 1 arg )
-    G->register_fct_meta ( "to_d", 1, "(x): convert x to floating-point number" );
-    G->register_fct_d_i  ( "to_d", func_to_d );
-    G->register_fct_d_d  ( "to_d", func_to_d );
-    G->register_fct_d_s  ( "to_d", func_to_d );
-    G->register_fct_meta ( "pop", 1, "(x): do nothing" );
-    G->register_fct_0_i  ( "pop", func_pop );
-    G->register_fct_0_d  ( "pop", func_pop );
-    G->register_fct_0_s  ( "pop", func_pop );
-    G->register_fct_meta ( "exit", 1, "(x): exit(x)" );
-    G->register_fct_i_i  ( "exit", func_exit );
-    G->register_fct_meta ( "ln", 1, "(x): natural logarithm of x, or 0 if x<=0" );
-    G->register_fct_d_d  ( "ln", func_ln );
-    G->register_fct_e_e  ( "ln", func_ln );
-    G->register_fct_meta ( "lg", 1, "(x): decadic logarithm of x, or 0 if x<=0" );
-    G->register_fct_d_d  ( "lg", func_lg );
-    G->register_fct_e_e  ( "lg", func_lg );
-    G->register_fct_meta ( "sqrt", 1, "(x): square root of x, or 0 if x<0" );
-    G->register_fct_d_d  ( "sqrt", func_sqrt );
-    G->register_fct_e_e  ( "sqrt", func_sqrt );
-    G->register_fct_meta ( "abs", 1, "(x): absolute value of x" );
-    G->register_fct_i_i  ( "abs", func_abs );
-    G->register_fct_d_d  ( "abs", func_abs );
-    G->register_fct_e_e  ( "abs", func_abs );
-    G->register_fct_meta ( "sign", 1, "(x): sign of x" );
-    G->register_fct_i_i  ( "sign", func_sign );
-    G->register_fct_d_d  ( "sign", func_sign );
-    G->register_fct_e_e  ( "sign", func_sign );
-    G->register_fct_meta ( "exp", 1, "(x): exponential function of x" );
-    G->register_fct_d_d  ( "exp", func_exp );
-    G->register_fct_e_e  ( "exp", func_exp );
-    G->register_fct_meta ( "sin", 1, "(x): sine of x (where x in radian)" );
-    G->register_fct_d_d  ( "sin", func_sin );
-    G->register_fct_e_e  ( "sin", func_sin );
-    G->register_fct_meta ( "cos", 1, "(x): cosine of x (where x in radian)" );
-    G->register_fct_d_d  ( "cos", func_cos );
-    G->register_fct_e_e  ( "cos", func_cos );
-    G->register_fct_meta ( "tan", 1, "(x): tangent of x (where x in radian)" );
-    G->register_fct_d_d  ( "tan", func_tan );
-    G->register_fct_meta ( "cot", 1, "(x): cotangent of x (where x in radian)" );
-    G->register_fct_d_d  ( "cot", func_cot );
-    G->register_fct_meta ( "sind", 1, "(x): sine of x (where x in degrees)" );
-    G->register_fct_d_d  ( "sind", func_sind );
-    G->register_fct_meta ( "cosd", 1, "(x): cosine of x (where x in degrees)" );
-    G->register_fct_d_d  ( "cosd", func_cosd );
-    G->register_fct_meta ( "tand", 1, "(x): tangent of x (where x in degrees)" );
-    G->register_fct_d_d  ( "tand", func_tand );
-    G->register_fct_meta ( "cotd", 1, "(x): cotangent of x (where x in degrees)" );
-    G->register_fct_d_d  ( "cotd", func_cotd );
-    G->register_fct_meta ( "asin", 1, "(x): arc sine of x (result is in radian; 0 if |x|>1)" );
-    G->register_fct_d_d  ( "asin", func_asin );
-    G->register_fct_meta ( "acos", 1, "(x): arc cosine of x (result is in radian; 0 if |x|>1)" );
-    G->register_fct_d_d  ( "acos", func_acos );
-    G->register_fct_meta ( "atan", 1, "(x): arc tangent of x (result is in radian)" );
-    G->register_fct_d_d  ( "atan", func_atan );
-    G->register_fct_meta ( "acot", 1, "(x): arc cotangent of x (result is in radian)" );
-    G->register_fct_d_d  ( "acot", func_acot );
-    G->register_fct_meta ( "asind", 1, "(x): arc sine of x (result is in degrees; 0 if |x|>1)" );
-    G->register_fct_d_d  ( "asind", func_asind );
-    G->register_fct_meta ( "acosd", 1, "(x): arc cosine of x (result is in degrees; 0 if |x|>1)" );
-    G->register_fct_d_d  ( "acosd", func_acosd );
-    G->register_fct_meta ( "atand", 1, "(x): arc tangent of x (result is in degrees)" );
-    G->register_fct_d_d  ( "atand", func_atand );
-    G->register_fct_meta ( "acotd", 1, "(x): arc cotangent of x (result is in degrees)" );
-    G->register_fct_d_d  ( "acotd", func_acotd );
-    G->register_fct_meta ( "sinh", 1, "(x): hyperbolic sine of x" );
-    G->register_fct_d_d  ( "sinh", func_sinh );
-    G->register_fct_meta ( "cosh", 1, "(x): hyperbolic cosine of x" );
-    G->register_fct_d_d  ( "cosh", func_cosh );
-    G->register_fct_meta ( "tanh", 1, "(x): hyperbolic tangent of x" );
-    G->register_fct_d_d  ( "tanh", func_tanh );
-    G->register_fct_meta ( "coth", 1, "(x): hyperbolic tangent of x" );
-    G->register_fct_d_d  ( "coth", func_coth );
-    G->register_fct_meta ( "j0", 1, "(x): spherical Bessel function x" );
-    G->register_fct_d_d  ( "j0", func_j0 );
-    G->register_fct_meta ( "j1", 1, "(x): spherical Bessel function x" );
-    G->register_fct_d_d  ( "j1", func_j1 );
-    G->register_fct_meta ( "fac", 1, "(x): factorial of nearest integer of x" );
-    G->register_fct_d_d  ( "fac", func_fac );
-    G->register_fct_meta ( "cata", 1, "(x): Catalan number of nearest integer of x" );
-    G->register_fct_d_d  ( "cata", func_cata );
-    G->register_fct_meta ( "gamma", 1, "(x): gamma function of x (i.e. factorial of x-1)" );
-    G->register_fct_d_d  ( "gamma", func_gamma );
-    G->register_fct_meta ( "lgamma", 1, "(x): ln of gamma of x" );
-    G->register_fct_d_d  ( "lgamma", func_lgamma );
-    G->register_fct_meta ( "debye1", 1, "(x): Debye function D1 of x" );
-    G->register_fct_d_d  ( "debye1", func_debye1 );
-    G->register_fct_meta ( "debye3", 1, "(x): Debye function D3 of x" );
-    G->register_fct_d_d  ( "debye3", func_debye3 );
-    G->register_fct_meta ( "debyeu2", 1, "(x): Debye mean squared displacement's temperature dependence" );
-    G->register_fct_d_d  ( "debyeu2", func_debye_msd );
-    G->register_fct_meta ( "debyeui", 1, "(x): Debye internal energy" );
-    G->register_fct_d_d  ( "debyeui", func_debye_ui );
-    G->register_fct_meta ( "debyecv", 1, "(x): Debye heat capacity" );
-    G->register_fct_d_d  ( "debyecv", func_debye_cv );
-    G->register_fct_meta ( "erfP", 1, "(x): ?" );
-    G->register_fct_d_d  ( "erfP", func_erfP );
-    G->register_fct_meta ( "erfQ", 1, "(x): ?" );
-    G->register_fct_d_d  ( "erfQ", func_erfQ );
-    G->register_fct_meta ( "erf", 1, "(x): error function of x" );
-    G->register_fct_d_d  ( "erf", func_erf );
-    G->register_fct_meta ( "erfc", 1, "(x): complementary error function of x" );
-    G->register_fct_d_d  ( "erfc", func_erfc );
-    G->register_fct_meta ( "erfi", 1, "(x): imaginary error function of x" );
-    G->register_fct_d_d  ( "erfi", func_erfi );
-    G->register_fct_meta ( "dawson", 1, "(x): Dawson function of x" );
-    G->register_fct_d_d  ( "dawson", func_dawson );
-    G->register_fct_meta ( "sinc", 1, "(x): sinus cardinalis, sin(x)/x" );
-    G->register_fct_d_d  ( "sinc", func_sinc );
-    G->register_fct_meta ( "ceil", 1, "(x): the smallest integer i with i>=x" );
-    G->register_fct_i_d  ( "ceil", func_ceil );
-    G->register_fct_meta ( "floor", 1, "(x): the largest integer i with i<=x" );
-    G->register_fct_i_d  ( "floor", func_floor );
-    G->register_fct_meta ( "nint", 1, "(x): the integer nearest to x" );
-    G->register_fct_i_d  ( "nint", func_nint );
-
-    G->register_fct_meta ( "diehl", 1, "(cauchywid/gausswid): normalized convolution gauss(*)cauchy" );
-    G->register_fct_d_d  ( "diehl", func_diehl );
-    G->register_fct_meta ( "lndiehl", 1, "(cauchywid/gausswid): ln of normalized convolution gauss(*)cauchy" );
-    G->register_fct_d_d  ( "lndiehl", func_lndiehl );
+    m = { "to_d", 1, "(x): convert x to floating-point number" };
+    G->register_fct_d_i  ( m, func_to_d );
+    G->register_fct_d_d  ( m, func_to_d );
+    G->register_fct_d_s  ( m, func_to_d );
+    m = { "pop", 1, "(x): do nothing" };
+    G->register_fct_0_i  ( m, func_pop );
+    G->register_fct_0_d  ( m, func_pop );
+    G->register_fct_0_s  ( m, func_pop );
+    m = { "exit", 1, "(x): exit(x)" };
+    G->register_fct_i_i  ( m, func_exit );
+    m = { "ln", 1, "(x): natural logarithm of x, or 0 if x<=0" };
+    G->register_fct_d_d  ( m, func_ln );
+    G->register_fct_e_e  ( m, func_ln );
+    m = { "lg", 1, "(x): decadic logarithm of x, or 0 if x<=0" };
+    G->register_fct_d_d  ( m, func_lg );
+    G->register_fct_e_e  ( m, func_lg );
+    m = { "sqrt", 1, "(x): square root of x, or 0 if x<0" };
+    G->register_fct_d_d  ( m, func_sqrt );
+    G->register_fct_e_e  ( m, func_sqrt );
+    m = { "abs", 1, "(x): absolute value of x" };
+    G->register_fct_i_i  ( m, func_abs );
+    G->register_fct_d_d  ( m, func_abs );
+    G->register_fct_e_e  ( m, func_abs );
+    m = { "sign", 1, "(x): sign of x" };
+    G->register_fct_i_i  ( m, func_sign );
+    G->register_fct_d_d  ( m, func_sign );
+    G->register_fct_e_e  ( m, func_sign );
+    m = { "exp", 1, "(x): exponential function of x" };
+    G->register_fct_d_d  ( m, func_exp );
+    G->register_fct_e_e  ( m, func_exp );
+    m = { "sin", 1, "(x): sine of x (where x in radian)" };
+    G->register_fct_d_d  ( m, func_sin );
+    G->register_fct_e_e  ( m, func_sin );
+    m = { "cos", 1, "(x): cosine of x (where x in radian)" };
+    G->register_fct_d_d  ( m, func_cos );
+    G->register_fct_e_e  ( m, func_cos );
+    m = { "tan", 1, "(x): tangent of x (where x in radian)" };
+    G->register_fct_d_d  ( m, func_tan );
+    m = { "cot", 1, "(x): cotangent of x (where x in radian)" };
+    G->register_fct_d_d  ( m, func_cot );
+    m = { "sind", 1, "(x): sine of x (where x in degrees)" };
+    G->register_fct_d_d  ( m, func_sind );
+    m = { "cosd", 1, "(x): cosine of x (where x in degrees)" };
+    G->register_fct_d_d  ( m, func_cosd );
+    m = { "tand", 1, "(x): tangent of x (where x in degrees)" };
+    G->register_fct_d_d  ( m, func_tand );
+    m = { "cotd", 1, "(x): cotangent of x (where x in degrees)" };
+    G->register_fct_d_d  ( m, func_cotd );
+    m = { "asin", 1, "(x): arc sine of x (result is in radian; 0 if |x|>1)" };
+    G->register_fct_d_d  ( m, func_asin );
+    m = { "acos", 1, "(x): arc cosine of x (result is in radian; 0 if |x|>1)" };
+    G->register_fct_d_d  ( m, func_acos );
+    m = { "atan", 1, "(x): arc tangent of x (result is in radian)" };
+    G->register_fct_d_d  ( m, func_atan );
+    m = { "acot", 1, "(x): arc cotangent of x (result is in radian)" };
+    G->register_fct_d_d  ( m, func_acot );
+    m = { "asind", 1, "(x): arc sine of x (result is in degrees; 0 if |x|>1)" };
+    G->register_fct_d_d  ( m, func_asind );
+    m = { "acosd", 1, "(x): arc cosine of x (result is in degrees; 0 if |x|>1)" };
+    G->register_fct_d_d  ( m, func_acosd );
+    m = { "atand", 1, "(x): arc tangent of x (result is in degrees)" };
+    G->register_fct_d_d  ( m, func_atand );
+    m = { "acotd", 1, "(x): arc cotangent of x (result is in degrees)" };
+    G->register_fct_d_d  ( m, func_acotd );
+    m = { "sinh", 1, "(x): hyperbolic sine of x" };
+    G->register_fct_d_d  ( m, func_sinh );
+    m = { "cosh", 1, "(x): hyperbolic cosine of x" };
+    G->register_fct_d_d  ( m, func_cosh );
+    m = { "tanh", 1, "(x): hyperbolic tangent of x" };
+    G->register_fct_d_d  ( m, func_tanh );
+    m = { "coth", 1, "(x): hyperbolic tangent of x" };
+    G->register_fct_d_d  ( m, func_coth );
+    m = { "j0", 1, "(x): spherical Bessel function x" };
+    G->register_fct_d_d  ( m, func_j0 );
+    m = { "j1", 1, "(x): spherical Bessel function x" };
+    G->register_fct_d_d  ( m, func_j1 );
+    m = { "fac", 1, "(x): factorial of nearest integer of x" };
+    G->register_fct_d_d  ( m, func_fac );
+    m = { "cata", 1, "(x): Catalan number of nearest integer of x" };
+    G->register_fct_d_d  ( m, func_cata );
+    m = { "gamma", 1, "(x): gamma function of x (i.e. factorial of x-1)" };
+    G->register_fct_d_d  ( m, func_gamma );
+    m = { "lgamma", 1, "(x): ln of gamma of x" };
+    G->register_fct_d_d  ( m, func_lgamma );
+    m = { "debye1", 1, "(x): Debye function D1 of x" };
+    G->register_fct_d_d  ( m, func_debye1 );
+    m = { "debye3", 1, "(x): Debye function D3 of x" };
+    G->register_fct_d_d  ( m, func_debye3 );
+    m = { "debyeu2", 1, "(x): Debye mean squared displacement's temperature dependence" };
+    G->register_fct_d_d  ( m, func_debye_msd );
+    m = { "debyeui", 1, "(x): Debye internal energy" };
+    G->register_fct_d_d  ( m, func_debye_ui );
+    m = { "debyecv", 1, "(x): Debye heat capacity" };
+    G->register_fct_d_d  ( m, func_debye_cv );
+    m = { "erfP", 1, "(x): ?" };
+    G->register_fct_d_d  ( m, func_erfP );
+    m = { "erfQ", 1, "(x): ?" };
+    G->register_fct_d_d  ( m, func_erfQ );
+    m = { "erf", 1, "(x): error function of x" };
+    G->register_fct_d_d  ( m, func_erf );
+    m = { "erfc", 1, "(x): complementary error function of x" };
+    G->register_fct_d_d  ( m, func_erfc );
+    m = { "erfi", 1, "(x): imaginary error function of x" };
+    G->register_fct_d_d  ( m, func_erfi );
+    m = { "dawson", 1, "(x): Dawson function of x" };
+    G->register_fct_d_d  ( m, func_dawson );
+    m = { "sinc", 1, "(x): sinus cardinalis, sin(x)/x" };
+    G->register_fct_d_d  ( m, func_sinc );
+    m = { "ceil", 1, "(x): the smallest integer i with i>=x" };
+    G->register_fct_i_d  ( m, func_ceil );
+    m = { "floor", 1, "(x): the largest integer i with i<=x" };
+    G->register_fct_i_d  ( m, func_floor );
+    m = { "nint", 1, "(x): the integer nearest to x" };
+    G->register_fct_i_d  ( m, func_nint );
+
+    m = { "diehl", 1, "(cauchywid/gausswid): normalized convolution gauss(*)cauchy" };
+    G->register_fct_d_d  ( m, func_diehl );
+    m = { "lndiehl", 1, "(cauchywid/gausswid): ln of normalized convolution gauss(*)cauchy" };
+    G->register_fct_d_d  ( m, func_lndiehl );
 
     // f(2 args)
-    G->register_fct_meta ( "exit_if", 2, "(x,s): throw s if x" );
-    G->register_fct_i_is ( "exit_if", func_exit_if );
-    G->register_fct_meta ( "exit_unless", 1, "(x,s): throw s if !x" );
-    G->register_fct_i_is ( "exit_unless", func_exit_unless );
-    G->register_fct_meta ( "min2", 2, "(x,y): the smaller of the two arguments x and y" );
-    G->register_fct_i_ii ( "min2", func_min );
-    G->register_fct_d_dd ( "min2", func_min );
-    G->register_fct_meta ( "max2", 2, "(x,y): the smaller of the two arguments x and y" );
-    G->register_fct_i_ii ( "max2", func_max );
-    G->register_fct_d_dd ( "max2", func_max );
-    G->register_fct_meta ( "ran", 2, "(x,y): a random number between x and y" );
-    G->register_fct_d_dd ( "ran", func_ran );
-
-    G->register_fct_meta ( "gauss", 2, "(x,s): the normalized Gaussian exp(-x^2/2/s^2)/sqrt(2 pi)/s" );
-    G->register_fct_d_dd ( "gauss", func_gauss );
-    G->register_fct_meta ( "gnn", 2, "(x,s): the unnormalized Gaussian exp(-x^2/2/s^2)" );
-    G->register_fct_d_dd ( "gnn", func_gaussnn );
-    G->register_fct_meta ( "cauchy", 2, "(x,w): the Cauchy-Lorentz function ?/(x^2+w^2)" );
-    G->register_fct_d_dd ( "cauchy", func_cauchy );
+    m = { "exit_if", 2, "(x,s): throw s if x" };
+    G->register_fct_i_is ( m, func_exit_if );
+    m = { "exit_unless", 1, "(x,s): throw s if !x" };
+    G->register_fct_i_is ( m, func_exit_unless );
+    m = { "min2", 2, "(x,y): the smaller of the two arguments x and y" };
+    G->register_fct_i_ii ( m, func_min );
+    G->register_fct_d_dd ( m, func_min );
+    m = { "max2", 2, "(x,y): the smaller of the two arguments x and y" };
+    G->register_fct_i_ii ( m, func_max );
+    G->register_fct_d_dd ( m, func_max );
+    m = { "ran", 2, "(x,y): a random number between x and y" };
+    G->register_fct_d_dd ( m, func_ran );
+
+    m = { "gauss", 2, "(x,s): the normalized Gaussian exp(-x^2/2/s^2)/sqrt(2 pi)/s" };
+    G->register_fct_d_dd ( m, func_gauss );
+    m = { "gnn", 2, "(x,s): the unnormalized Gaussian exp(-x^2/2/s^2)" };
+    G->register_fct_d_dd ( m, func_gaussnn );
+    m = { "cauchy", 2, "(x,w): the Cauchy-Lorentz function ?/(x^2+w^2)" };
+    G->register_fct_d_dd ( m, func_cauchy );
 
     // f(3 args)
-    G->register_fct_meta ( "rehavneg", 3, "(x,y,z): real part of the Havriliak-Negami function" );
-    G->register_fct_d_ddd( "rehavneg", func_re_havneg );
-    G->register_fct_meta ( "imhavneg", 3, "(x,y,z): imaginary part of the Havriliak-Negami function" );
-    G->register_fct_d_ddd( "imhavneg", func_im_havneg );
-    G->register_fct_meta ( "q4w", 3, "(x,y,z): ?" );
-    G->register_fct_d_ddd( "q4w", func_q4w );
-    G->register_fct_meta ( "cauchy2", 3, "(x,y,z): ?" );
-    G->register_fct_d_ddd( "cauchy2", func_cauchy2 );
-    G->register_fct_meta ( "kwwc", 3, "(w,tau,b): Fourier cosine transform (t->w) of exp((t/tau)^b)" );
-    G->register_fct_d_ddd( "kwwc", func_kwwc );
-    G->register_fct_meta ( "kwws", 3, "(w,tau,b): Fourier sine transform (t->w) of exp((t/tau)^b)" );
-    G->register_fct_d_ddd( "kwws", func_kwws );
-    G->register_fct_meta ( "kwwp", 3, "(w,tau,b): primitive of Fourier cosine transform (t->w) of exp((t/tau)^b)" );
-    G->register_fct_d_ddd( "kwwp", func_kwwp );
-    G->register_fct_meta ( "voigt", 3, "(x,sigma,gamma): convolution of Gaussian(x,sigma) and Lorentzian(x,gamma)" );
-    G->register_fct_d_ddd( "voigt", func_voigt );
-    G->register_fct_meta ( "zorn", 3, "(I,<I>,s): Zorn's multiple-scattering corrected elastic intensity" );
-    G->register_fct_d_ddd( "zorn", func_zorn );
-    G->register_fct_meta ( "zorn2", 3, "(q,<u^2>,s): Zorn's multiple-scattering corrected Gaussian elastic intensity for Si111" );
-    G->register_fct_d_ddd( "zorn2", func_zorn_gauss );
-    G->register_fct_meta ( "rrdm", 3, "(w*t0,EA_mean/T,EA_stdv/EA_mean: rotational rate distribution model" );
-    G->register_fct_d_ddd( "rrdm", func_rrdm );
-    G->register_fct_meta ( "ornuhl", 3, "(w,a,b) Ornstein-Uhlenbeck spectrum FT[exp(-|b|t-a(1-exp(-t)))]" );
-    G->register_fct_d_ddd( "ornuhl", func_ornuhl );
-    G->register_fct_meta ( "rotdiff", 3, "(w,tau,qb: rotational diffusion spectrum)" );
-    G->register_fct_d_ddd( "rotdiff", func_rotdiff );
+    m = { "rehavneg", 3, "(x,y,z): real part of the Havriliak-Negami function" };
+    G->register_fct_d_ddd( m, func_re_havneg );
+    m = { "imhavneg", 3, "(x,y,z): imaginary part of the Havriliak-Negami function" };
+    G->register_fct_d_ddd( m, func_im_havneg );
+    m = { "q4w", 3, "(x,y,z): ?" };
+    G->register_fct_d_ddd( m, func_q4w );
+    m = { "cauchy2", 3, "(x,y,z): ?" };
+    G->register_fct_d_ddd( m, func_cauchy2 );
+    m = { "kwwc", 3, "(w,tau,b): Fourier cosine transform (t->w) of exp((t/tau)^b)" };
+    G->register_fct_d_ddd( m, func_kwwc );
+    m = { "kwws", 3, "(w,tau,b): Fourier sine transform (t->w) of exp((t/tau)^b)" };
+    G->register_fct_d_ddd( m, func_kwws );
+    m = { "kwwp", 3, "(w,tau,b): primitive of Fourier cosine transform (t->w) of exp((t/tau)^b)" };
+    G->register_fct_d_ddd( m, func_kwwp );
+    m = { "voigt", 3, "(x,sigma,gamma): convolution of Gaussian(x,sigma) and Lorentzian(x,gamma)" };
+    G->register_fct_d_ddd( m, func_voigt );
+    m = { "zorn", 3, "(I,<I>,s): Zorn's multiple-scattering corrected elastic intensity" };
+    G->register_fct_d_ddd( m, func_zorn );
+    m = { "zorn2", 3, "(q,<u^2>,s): Zorn's multiple-scattering corrected Gaussian elastic intensity for Si111" };
+    G->register_fct_d_ddd( m, func_zorn_gauss );
+    m = { "rrdm", 3, "(w*t0,EA_mean/T,EA_stdv/EA_mean: rotational rate distribution model" };
+    G->register_fct_d_ddd( m, func_rrdm );
+    m = { "ornuhl", 3, "(w,a,b) Ornstein-Uhlenbeck spectrum FT[exp(-|b|t-a(1-exp(-t)))]" };
+    G->register_fct_d_ddd( m, func_ornuhl );
+    m = { "rotdiff", 3, "(w,tau,qb: rotational diffusion spectrum)" };
+    G->register_fct_d_ddd( m, func_rotdiff );
 }
diff --git a/pub/lib/fregistry.cpp b/pub/lib/fregistry.cpp
index 7ab51554ee0424379ce6881f593f41367896950e..84c2f04f1cc2ff59f0bb8f5bfa28f5e0e0567736 100644
--- a/pub/lib/fregistry.cpp
+++ b/pub/lib/fregistry.cpp
@@ -24,9 +24,8 @@ SFuncRegistry* SFuncRegistry::instance = nullptr;
 
 SFuncRegistry::~SFuncRegistry()
 {
-    for ( const CFunc* F: FList ) {
+    for ( const CFunc* F: FList )
         delete F;
-    };
 }
 
 
@@ -76,29 +75,19 @@ void SFuncRegistry::display_functions() const
 }
 
 
-//! Registers meta information for a given function name.
-//! Must be called before typed implementations are registered.
-
-void SFuncRegistry::register_fct_meta( const char* _tag, int _narg, const char* _explanation, int _precedence )
-{
-    CFunc* f( new CFunc( _tag, _narg, _explanation, _precedence ) );
-    FMap.insert( std::make_pair( _tag, f ) );
-    FList.push_back( f );
-}
-
-
 //! Registers a typed function implementation.
 //! The function name must have been previously registered using register_fct_meta.
 
 void SFuncRegistry::register_fct_template(
-    const char* _tag, const char* _outtype, const char* _intypes, funcPtr _f )
+    const CFuncMetadata& _m, const char* _outtype, const char* _intypes, funcPtr _f )
 {
-    auto pos = FMap.find(_tag);
+    auto pos = FMap.find(_m.tag);
+    CFunc* F;
     if( pos == FMap.end() ) {
-        cerr << "Cannot register fct_" << _outtype << "_" << _intypes << "_" << _tag <<
-                  ": no meta entry\n";
-        exit(1);
-    }
-    const auto tf = new CTypedFunc( _outtype, _intypes, _f );
-    pos->second->tyfuList.push_back( tf );
+        F = new CFunc( _m );
+        FMap.insert( std::make_pair( _m.tag, F ) );
+        FList.push_back( F );
+    } else
+        F = pos->second;
+    F->tyfuList.push_back( new CTypedFunc( _outtype, _intypes, _f ) );
 }
diff --git a/pub/lib/fregistry.hpp b/pub/lib/fregistry.hpp
index 890b1e0baf4b6f65d25661b2b138359febab0143..6ed989d14c796bb6934b1d1b95c975bd671c87ff 100644
--- a/pub/lib/fregistry.hpp
+++ b/pub/lib/fregistry.hpp
@@ -58,7 +58,7 @@ class SFuncRegistry {
     vector<const class CFunc*> FList;    //! sorted array, for help text
 
     void register_fct_template(
-        const char* _tag, const char* _outtype, const char* _intypes, funcPtr _f );
+        const CFuncMetadata& _m, const char* _outtype, const char* _intypes, funcPtr _f );
 
  public:
     static SFuncRegistry* get_instance()
@@ -76,88 +76,84 @@ class SFuncRegistry {
     void display_functions() const;
     void display_operators() const;
 
-    void register_fct_meta(
-        const char* _tag, int _narg, const char* _explanation, int _precedence=0 );
+    void register_fct_0_i( const CFuncMetadata& _m, func_0_i _f )
+        { register_fct_template( _m, "0", "i", (funcPtr)_f ); }
 
-    void register_fct_0_i( const char* _tag, func_0_i _f )
-        { register_fct_template( _tag, "0", "i", (funcPtr)_f ); }
+    void register_fct_0_d( const CFuncMetadata& _m, func_0_d _f )
+        { register_fct_template( _m, "0", "d", (funcPtr)_f ); }
 
-    void register_fct_0_d( const char* _tag, func_0_d _f )
-        { register_fct_template( _tag, "0", "d", (funcPtr)_f ); }
+    void register_fct_0_s( const CFuncMetadata& _m, func_0_s _f )
+        {    register_fct_template( _m, "0", "s", (funcPtr)_f ); }
 
-    void register_fct_0_s( const char* _tag, func_0_s _f )
-        {    register_fct_template( _tag, "0", "s", (funcPtr)_f ); }
+    void register_fct_i_i( const CFuncMetadata& _m, func_i_i _f )
+        { register_fct_template( _m, "i", "i", (funcPtr)_f ); }
 
-    void register_fct_i_i( const char* _tag, func_i_i _f )
-        { register_fct_template( _tag, "i", "i", (funcPtr)_f ); }
+    void register_fct_i_d( const CFuncMetadata& _m, func_i_d _f )
+        { register_fct_template( _m, "i", "d", (funcPtr)_f ); }
 
-    void register_fct_i_d( const char* _tag, func_i_d _f )
-        { register_fct_template( _tag, "i", "d", (funcPtr)_f ); }
+    void register_fct_i_s( const CFuncMetadata& _m, func_i_s _f )
+        { register_fct_template( _m, "i", "s", (funcPtr)_f ); }
 
-    void register_fct_i_s( const char* _tag, func_i_s _f )
-        { register_fct_template( _tag, "i", "s", (funcPtr)_f ); }
+    void register_fct_d_i( const CFuncMetadata& _m, func_d_i _f )
+        { register_fct_template( _m, "d", "i", (funcPtr)_f ); }
 
-    void register_fct_d_i( const char* _tag, func_d_i _f )
-        { register_fct_template( _tag, "d", "i", (funcPtr)_f ); }
+    void register_fct_d_d( const CFuncMetadata& _m, func_d_d _f )
+        { register_fct_template( _m, "d", "d", (funcPtr)_f ); }
 
-    void register_fct_d_d( const char* _tag, func_d_d _f )
-        { register_fct_template( _tag, "d", "d", (funcPtr)_f ); }
+    void register_fct_d_s( const CFuncMetadata& _m, func_d_s _f )
+        { register_fct_template( _m, "d", "s", (funcPtr)_f ); }
 
-    void register_fct_d_s( const char* _tag, func_d_s _f )
-        { register_fct_template( _tag, "d", "s", (funcPtr)_f ); }
+    void register_fct_e_e( const CFuncMetadata& _m, func_e_e _f )
+        { register_fct_template( _m, "e", "e", (funcPtr)_f ); }
 
-    void register_fct_e_e( const char* _tag, func_e_e _f )
-        { register_fct_template( _tag, "e", "e", (funcPtr)_f ); }
+    void register_fct_i_ii( const CFuncMetadata& _m, func_i_ii _f )
+        { register_fct_template( _m, "i", "ii", (funcPtr)_f ); }
 
-    void register_fct_i_ii( const char* _tag, func_i_ii _f )
-        { register_fct_template( _tag, "i", "ii", (funcPtr)_f ); }
+    void register_fct_i_id( const CFuncMetadata& _m, func_i_id _f )
+        { register_fct_template( _m, "i", "id", (funcPtr)_f ); }
 
-    void register_fct_i_id( const char* _tag, func_i_id _f )
-        { register_fct_template( _tag, "i", "id", (funcPtr)_f ); }
+    void register_fct_i_is( const CFuncMetadata& _m, func_i_is _f )
+        { register_fct_template( _m, "i", "is", (funcPtr)_f ); }
 
-    void register_fct_i_is( const char* _tag, func_i_is _f )
-        { register_fct_template( _tag, "i", "is", (funcPtr)_f ); }
+    void register_fct_i_di( const CFuncMetadata& _m, func_i_di _f )
+        { register_fct_template( _m, "i", "di", (funcPtr)_f ); }
 
-    void register_fct_i_di( const char* _tag, func_i_di _f )
-        { register_fct_template( _tag, "i", "di", (funcPtr)_f ); }
+    void register_fct_i_dd( const CFuncMetadata& _m, func_i_dd _f )
+        { register_fct_template( _m, "i", "dd", (funcPtr)_f ); }
 
-    void register_fct_i_dd( const char* _tag, func_i_dd _f )
-        { register_fct_template( _tag, "i", "dd", (funcPtr)_f ); }
+    void register_fct_i_si( const CFuncMetadata& _m, func_i_si _f )
+        { register_fct_template( _m, "i", "si", (funcPtr)_f ); }
 
-    void register_fct_i_si( const char* _tag, func_i_si _f )
-        { register_fct_template( _tag, "i", "si", (funcPtr)_f ); }
+    void register_fct_d_ii( const CFuncMetadata& _m, func_d_ii _f )
+        { register_fct_template( _m, "d", "ii", (funcPtr)_f ); }
 
-    void register_fct_d_ii( const char* _tag, func_d_ii _f )
-        { register_fct_template( _tag, "d", "ii", (funcPtr)_f ); }
+    void register_fct_d_dd( const CFuncMetadata& _m, func_d_dd _f )
+        { register_fct_template( _m, "d", "dd", (funcPtr)_f ); }
 
-    void register_fct_d_dd( const char* _tag, func_d_dd _f )
-        { register_fct_template( _tag, "d", "dd", (funcPtr)_f ); }
+    void register_fct_d_sd( const CFuncMetadata& _m, func_d_sd _f )
+        { register_fct_template( _m, "d", "sd", (funcPtr)_f ); }
 
-    void register_fct_d_sd( const char* _tag, func_d_sd _f )
-        { register_fct_template( _tag, "d", "sd", (funcPtr)_f ); }
+    void register_fct_e_dd( const CFuncMetadata& _m, func_e_dd _f )
+        { register_fct_template( _m, "e", "dd", (funcPtr)_f ); }
 
-    void register_fct_e_dd( const char* _tag, func_e_dd _f )
-        { register_fct_template( _tag, "e", "dd", (funcPtr)_f ); }
+    void register_fct_e_ee( const CFuncMetadata& _m, func_e_ee _f )
+        { register_fct_template( _m, "e", "ee", (funcPtr)_f ); }
 
-    void register_fct_e_ee( const char* _tag, func_e_ee _f )
-        { register_fct_template( _tag, "e", "ee", (funcPtr)_f ); }
+    void register_fct_e_se( const CFuncMetadata& _m, func_e_se _f )
+        { register_fct_template( _m, "e", "se", (funcPtr)_f ); }
 
-    void register_fct_e_se( const char* _tag, func_e_se _f )
-        { register_fct_template( _tag, "e", "se", (funcPtr)_f ); }
+    void register_fct_s_si( const CFuncMetadata& _m, func_s_si _f )
+        { register_fct_template( _m, "s", "si", (funcPtr)_f ); }
 
-    void register_fct_s_si( const char* _tag, func_s_si _f )
-        { register_fct_template( _tag, "s", "si", (funcPtr)_f ); }
+    void register_fct_s_ss( const CFuncMetadata& _m, func_s_ss _f )
+        { register_fct_template( _m, "s", "ss", (funcPtr)_f ); }
 
-    void register_fct_s_ss( const char* _tag, func_s_ss _f )
-        { register_fct_template( _tag, "s", "ss", (funcPtr)_f ); }
+    void register_fct_i_iii( const CFuncMetadata& _m, func_i_iii _f )
+        { register_fct_template( _m, "i", "iii", (funcPtr)_f ); }
 
-    void register_fct_i_iii( const char* _tag, func_i_iii _f )
-        { register_fct_template( _tag, "i", "iii", (funcPtr)_f ); }
-
-    void register_fct_d_ddd( const char* _tag, func_d_ddd _f )
-        { register_fct_template( _tag, "d", "ddd", (funcPtr)_f ); }
-
-    void register_fct_e_eee( const char* _tag, func_e_eee _f )
-        { register_fct_template( _tag, "e", "eee", (funcPtr)_f ); }
+    void register_fct_d_ddd( const CFuncMetadata& _m, func_d_ddd _f )
+        { register_fct_template( _m, "d", "ddd", (funcPtr)_f ); }
 
+    void register_fct_e_eee( const CFuncMetadata& _m, func_e_eee _f )
+        { register_fct_template( _m, "e", "eee", (funcPtr)_f ); }
 };
diff --git a/pub/lib/fstring.cpp b/pub/lib/fstring.cpp
index d471a4a07d36d28e96a9c4e9fded405e0fee7694..ee46a59e021cbd3a700ef9ba78c29c52e3a5b393 100644
--- a/pub/lib/fstring.cpp
+++ b/pub/lib/fstring.cpp
@@ -22,6 +22,7 @@ void func_cmd(string s) { frida_command( s ); } // TO CHECK: -> "eval" ? right a
 
 int func_len(string s) { return s.size(); }
 
+
 //**************************************************************************************************
 //*  Functions of two arguments
 //**************************************************************************************************
@@ -34,23 +35,25 @@ string func_mul(string s, int n)
     return ret;
 }
 
+
 //**************************************************************************************************
 //*  Registration
 //**************************************************************************************************
 
-//! Registers basic and arithmetic functions.
+//! Registers string functions.
 
 void fstring_initialize()
 {
-
     auto G = SFuncRegistry::get_instance();
+    CFuncMetadata m;
 
     // operators by precedence (which should agree with xax_yacc.ypp):
-    G->register_fct_s_si ( "*", func_mul );
+    m = { "*",   2, "a*b     [product]", 6 }; // TODO: copying this line from fbase is weird
+    G->register_fct_s_si ( m, func_mul );
 
     // f( 1 arg )
-    G->register_fct_meta ( "cmd", 1, "(s): execute s as Frida command" );
-    G->register_fct_0_s  ( "cmd", func_cmd );
-    G->register_fct_meta ( "len", 1, "(s): length of string s" );
-    G->register_fct_i_s  ( "len", func_len );
+    m = { "cmd", 1, "(s): execute s as Frida command" };
+    G->register_fct_0_s  ( m, func_cmd );
+    m = { "len", 1, "(s): length of string s" };
+    G->register_fct_i_s  ( m, func_len );
 }
diff --git a/pub/lib/func.hpp b/pub/lib/func.hpp
index 30ddea122b67683727bd0d19d58873902eedd200..c10252d3f1c36046514233f83df7794c1a78051e 100644
--- a/pub/lib/func.hpp
+++ b/pub/lib/func.hpp
@@ -13,6 +13,8 @@ typedef void (*funcPtr)(void); // generic pointer-to-function type
 
 class CCoord;
 
+//! A wrapper holding a function with fixed input and output types.
+
 class CTypedFunc {
  public:
     const string outtype;
@@ -21,18 +23,27 @@ class CTypedFunc {
     CTypedFunc( const char* _outtype, const char* _intypes, funcPtr _f )
         : outtype(_outtype), intypes(_intypes), f(_f) {};
 };
-    
-//! A wrapper holding a function.
 
-class CFunc {
+//! Metadata for an untyped function.
+
+class CFuncMetadata {
  public:
-    const string tag;
+    string tag;
     int narg;
-    const char* explanation;
+    string explanation;
     int precedence;
-    vector<const CTypedFunc*> tyfuList; //! List of available typed function instances.
-    CFunc( const char* _tag, int _narg, const char* _explanation, int _precedence=0 )
+    CFuncMetadata() {}
+    CFuncMetadata( string _tag, int _narg, string _explanation, int _precedence=0 )
         : tag(_tag), narg(_narg), explanation(_explanation), precedence(_precedence) {}
+};
+
+
+//! A wrapper holding function metadata and implementations for various input and output types.
+
+class CFunc : public CFuncMetadata {
+ public:
+    CFunc( const CFuncMetadata& _m ) : CFuncMetadata( _m ) {}
+    vector<const CTypedFunc*> tyfuList; //! List of available typed function instances.
     const CTypedFunc* find_exact_tyfu( string intypes ) const;
     const CTypedFunc* find_tyfu( string intypes, bool want_error ) const;
     class CCoord coord( const CCoord& co ) const;
diff --git a/pub/lib/toplevel.cpp b/pub/lib/toplevel.cpp
index 19e05c62ddfd5052e6a8d7c859f0a55a734ea7d3..f8b4a94a10b36c75fc3b762c0118d9c9ef66aca3 100644
--- a/pub/lib/toplevel.cpp
+++ b/pub/lib/toplevel.cpp
@@ -144,7 +144,7 @@ CFrida::CFrida()
     NGeni::initialize();
     NCvin::initialize();
 
-    if( !std::atexit( atexit_handler ) ) {
+    if( std::atexit( atexit_handler ) ) {
         cerr << "BUG: atexit registration failed\n";
         exit(EXIT_FAILURE);
     }