Yalantis/uCrop · error · CImgArgumentException

[cimg_appname_math_parser] CImg<%s>::%s: %s: Multiple argume

Error message

[cimg_appname_math_parser] CImg<%s>::%s: %s: Multiple arguments not allowed when first one is variadic, in macro definition '%s()', in expression '%s'.

What it means

When defining a macro whose first parameter is variadic (declared so it can absorb a variable number of arguments), no additional parameters may follow it. The parser throws CImgArgumentException if it finds more than one argument in a macro definition whose first argument is variadic.

Source

Thrown at ucrop/src/main/jni/CImg.h:18578

            // Assign user-defined macro.
            if (l_variable_name>2 && *ve1==')' && *ss!='(') {
              s0 = ve1; while (s0>ss && *s0!='(') --s0;
              if (cimg::is_varname(ss,s0 - ss) && std::strncmp(variable_name,"debug(",6) &&
                  std::strncmp(variable_name,"print(",6)) { // Valid macro name
                s0 = variable_name._data + (s0 - ss);
                *s0 = 0;
                s1 = variable_name._data + l_variable_name - 1; // Pointer to closing parenthesis
                CImg<charT>(variable_name._data,(unsigned int)(s0 - variable_name._data + 1)).move_to(macro_def,0);
                ++s; while (*s && cimg::is_blank(*s)) ++s;
                CImg<charT>(s,(unsigned int)(se - s + 1)).move_to(macro_body,0);

                bool is_variadic = false;
                p1 = 1; // Index of current parsed argument
                for (s = s0 + 1; s<=s1; ++p1, s = ns + 1) { // Parse function arguments
                  if (is_variadic && p1>1) {
                    _cimg_mp_strerr;
                    cimg::strellipsize(variable_name,64);
                    throw CImgArgumentException("[" cimg_appname "_math_parser] "
                                                "CImg<%s>::%s: %s: Multiple arguments not allowed when first one is "
                                                "variadic, in macro definition '%s()', in expression '%s'.",
                                                pixel_type(),_cimg_mp_calling_function,s_op,
                                                variable_name._data,s0);
                  }
                  if (p1>24) {
                    _cimg_mp_strerr;
                    cimg::strellipsize(variable_name,64);
                    throw CImgArgumentException("[" cimg_appname "_math_parser] "
                                                "CImg<%s>::%s: %s: Too much specified arguments (>24), in macro "
                                                "definition '%s()', in expression '%s'.",
                                                pixel_type(),_cimg_mp_calling_function,s_op,
                                                variable_name._data,s0);
                  }
                  while (*s && cimg::is_blank(*s)) ++s;
                  if (*s==')' && p1==1) break; // Function has no arguments
                  s2 = s; // Start of the argument name
                  is_sth = true; // is_valid_argument_name?

View on GitHub (pinned to f788b534b4)

Solutions

  1. Remove the extra arguments after the variadic parameter — keep only the single variadic argument.
  2. If you need fixed parameters, declare them explicitly instead of making the first one variadic.
  3. Split the macro into two versions: one with fixed args and one variadic.
  4. Check macro definitions for stray commas producing phantom extra arguments.

Example fix

// before
"myjoin(...,sep) : ..." // variadic first arg plus extra 'sep' -> throws
// after
"myjoin(...) : ..." // only the variadic argument; embed separator inline
Defensive patterns

Strategy: validation

Validate before calling

// reject macro definitions mixing a variadic first arg with extra parameters
if (macro_def_has_variadic_plus_extra_args(def)) return ERR_BAD_MACRO_DEF;
img.eval(expr_with_macros);

Try / catch

try {
  img.eval(expr);
} catch (const CImgArgumentException& e) {
  if (strstr(e.what(), "variadic")) {
    // fix the macro definition: keep only the variadic argument
  }
}

Prevention

When it happens

Trigger: Defining a macro like mymacro(...,x) or (... , a, b) — i.e. a variadic first parameter plus extra named parameters; e.g. "m(a,...) : ..." written so that after the variadic marker further arguments are parsed.

Common situations: Authors assuming C-style varargs semantics (variadic must be last, but CImg requires it be the only/first with no extras); converting functions with many args into variadic macros incorrectly.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


AI-assisted analysis of Yalantis/uCrop@f788b534b4 (2026-09-08). Data as JSON: /api/errors/c7608b070edf26de. Report an issue: GitHub.