Yalantis/uCrop · error · CImgArgumentException

[" cimg_appname "_math_parser] CImg<%s>::%s: Function '%s()'

Error message

[" cimg_appname "_math_parser] CImg<%s>::%s: Function '%s()': Number of specified arguments (%u) does not match macro declaration (defined for %s or %u arguments), in expression '%s'.

What it means

CImg's built-in math expression parser compiles user expressions (formulas passed to functions like fill(), get_math(), etc.). When the expression calls a named macro/function, the parser checks the argument count against the macro's declared signature. This error is thrown when a macro is declared to accept one of two possible argument counts (a variable-arity signature), and the call supplies a count matching neither.

Source

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

              user_macro = s0;
              level.swap(_level);
              pexpr.swap(_pexpr);
              expr.swap(_expr);
              _cimg_mp_return(pos);
            }

            if (arg3) { // Macro name matched but number of arguments does not
              CImg<uintT> sig_nargs(arg3);
              arg1 = 0;
              cimglist_for(macro_def,l) if (!std::strcmp(macro_def[l],variable_name))
                sig_nargs[arg1++] = (unsigned int)macro_def[l].back();
              _cimg_mp_strerr;
              cimg::strellipsize(variable_name,64);
              if (sig_nargs._width>1) {
                sig_nargs.sort();
                arg1 = sig_nargs.back();
                --sig_nargs._width;
                throw CImgArgumentException("[" cimg_appname "_math_parser] "
                                            "CImg<%s>::%s: Function '%s()': Number of specified arguments (%u) "
                                            "does not match macro declaration (defined for %s or %u arguments), "
                                            "in expression '%s'.",
                                            pixel_type(),_cimg_mp_calling_function,variable_name._data,
                                            p1,sig_nargs.value_string()._data,arg1,s0);
              } else {
                throw CImgArgumentException("[" cimg_appname "_math_parser] "
                                            "CImg<%s>::%s: Function '%s()': Number of specified arguments (%u) "
                                            "does not match macro declaration (defined for %u argument%s), "
                                            "in expression '%s'.",
                                            pixel_type(),_cimg_mp_calling_function,variable_name._data,
                                            p1,*sig_nargs,*sig_nargs!=1?"s":"",s0);
              }
            }
          }
        } // if (se1==')')

        // Char / string initializer.

View on GitHub (pinned to f788b534b4)

Solutions

  1. Count the arguments in the offending call and compare with the macro declaration shown in the message (%s or %u arguments).
  2. Add or remove arguments so the call matches one of the declared arities.
  3. Check the macro definition (or CImg version docs) for the exact accepted signatures.
  4. If building expressions programmatically, assert the arity before substitution.
  5. Pin/verify the CImg version if a previously working expression stopped compiling.

Example fix

// before
dimg.fill(mymacro(a,b,c)); // mymacro declared for 2 or 3 args
// after
dimg.fill(mymacro(a,b));   // matches declared 2-or-3 argument signature
Defensive patterns

Strategy: validation

Validate before calling

boolean validArity = (macroArityA == callArgCount) || (macroArityB == callArgCount);
if (!validArity) throw new IllegalArgumentException("mymacro expects " + macroArityA + " or " + macroArityB + " args, got " + callArgCount);

Try / catch

try {
    img.fill(expression);
} catch (CImgInstantiationException e) {
    if (e.getMessage().contains("does not match macro declaration")) {
        // log expression + expected arities from message, fix expression
    }
    throw e;
}

Prevention

When it happens

Trigger: Evaluating a CImg math expression that invokes a user-defined macro (via cimg_math macro injection or fill()) with an argument count that does not match the macro's declared dual signature (e.g. macro defined for 2-or-3 arguments but called with 1 or 4). The branch executes when sig_nargs._width>1, i.e. the macro declares more than one accepted arity.

Common situations: Hand-written fill() expressions reusing copy-pasted macros after editing their signature; library-version changes where built-in macro arities changed; dynamically generated expressions where argument counts are computed at runtime.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


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