Implicit declaration of function 'min'

14,904

Solution 1

On a non-Windows machine, you don't #include <windows.h> (due to the #ifdef and obvious other reasons). Windows.h pulls in WinDef.h, and WinDef.h contains:

#ifndef min
#define min(a,b)            (((a) < (b)) ? (a) : (b))
#endif

That's where he went!

You can implement the macro, use fmin() as mentioned (note the current math.h include is #ifdef'd out too), or if you're feeling really kind and want to give the linker exactly what it was looking for:

double min(double a, double b) {
    return a<b ? a : b;
}

Solution 2

How about using "double fmin(double x, double y)" instead of min as the following?

...
/* Include the standard ANSI C header for handling time functions. */
#include <time.h>

#include <math.h>
#define min(a,b) fmin(a,b)
...
Share:
14,904
Pietair
Author by

Pietair

Updated on June 25, 2022

Comments

  • Pietair
    Pietair almost 2 years

    I am using Matlab R2013b and Xcode 5.0.2 on my MacBook to mex a file called sfun_rttime.c using Matlab's command: mex sfun_rrtime.c

    This results in the following error message:

    sfun_rttime.c:108:26: warning: implicit declaration of function 'min' is invalid in
          C99 [-Wimplicit-function-declaration]
       while (t_diff < (dt - min(dt,t_execution))) {
                             ^
    1 warning generated.
    Undefined symbols for architecture x86_64:
      "_min", referenced from:
          _mdlOutputs in sfun_rttime.o
    ld: symbol(s) not found for architecture x86_64
    clang: error: linker command failed with exit code 1 (use -v to see invocation)
    
        mex: link of ' "sfun_rttime.mexmaci64"' failed.
    
    Unable to complete successfully.
    

    The .c file looks as follows:

    #define S_FUNCTION_LEVEL 2
    #define S_FUNCTION_NAME  sfun_rttime
    
    #define TIME_SCALE_FACTOR(S) ssGetSFcnParam(S,0)
    
    /* Need to include simstruc.h for the definition of the SimStruct and
     * its associated macro definitions. */
    #include <simstruc.h>
    
    #if defined(_WIN32)
    /* Include the windows SDK header for handling time functions. */
    #include <windows.h>
    #include <math.h>
    
    /* Function of the high performance counter (in seconds). */
    __inline double hightimer()
    {
        HANDLE hCurrentProcess = GetCurrentProcess();
        DWORD dwProcessAffinity;
        DWORD dwSystemAffinity;    
        LARGE_INTEGER frequency, counter;
        double sec_per_tick, total_ticks;
    
        /* force thread on first cpu */
        GetProcessAffinityMask(hCurrentProcess,&dwProcessAffinity,&dwSystemAffinity);
        SetProcessAffinityMask(hCurrentProcess, 1);
    
        /* retrieves the frequency of the high-resolution performance counter */
        QueryPerformanceFrequency(&frequency);
    
        /* retrieves the current value of the high-resolution performance counter */
        QueryPerformanceCounter(&counter);
    
         /* reset thread */
        SetProcessAffinityMask(hCurrentProcess,dwProcessAffinity);
    
        /* time in seconds */
        sec_per_tick = (double)1/(double)frequency.QuadPart;
        total_ticks = (double)counter.QuadPart;    
        return sec_per_tick*total_ticks;
    }   /* end hightimer */
    #else
    /* Include the standard ANSI C header for handling time functions. */
    #include <time.h>
    
    /* Function of the high performance counter (in seconds). */
    __inline double hightimer()
    {    
        return (double)clock()/CLOCKS_PER_SEC;
    }   /* end hightimer */
    #endif
    
    static void mdlInitializeSizes(SimStruct *S)
    {
       ssSetNumSFcnParams(S, 1);  /* Number of expected parameters */
       if (ssGetNumSFcnParams(S) != ssGetSFcnParamsCount(S)) return;
        ssSetNumContStates(S, 0);
        ssSetNumDiscStates(S, 1);
       if (!ssSetNumInputPorts(S, 0)) return;
       if (!ssSetNumOutputPorts(S, 1)) return;
       ssSetOutputPortWidth(S, 0, 1);
       ssSetNumSampleTimes(S, 1);
       ssSetNumRWork(S, 1);
       ssSetNumIWork(S, 0);
       ssSetNumPWork(S, 0);
       ssSetNumModes(S, 0);
       ssSetNumNonsampledZCs(S, 0);
       ssSetOptions(S, 0);
    }
    
    #define MDL_INITIALIZE_SAMPLE_TIMES
    static void mdlInitializeSampleTimes(SimStruct *S)
    {
       ssSetSampleTime(S, 0, CONTINUOUS_SAMPLE_TIME);
       ssSetOffsetTime(S, 0, 0.0);
    }
    
    #define MDL_START
    static void mdlStart(SimStruct *S)
    {
       ssSetRWorkValue(S,0,ssGetTStart(S));
    }
    
    static void mdlOutputs(SimStruct *S, int_T tid)
    {
       double            *t_x = ssGetDiscStates(S);
       double            *t_y = ssGetOutputPortRealSignal(S,0);
       double             t_previousSimTime = ssGetRWorkValue(S,0);
       const double      *scaleFactor = mxGetPr(TIME_SCALE_FACTOR(S));
       time_T             t_SimTime = ssGetT(S);
       double             t_diff = 0.0;
       double             dt;
       double             t_current;
       double             t_0;
       double             t_previous;
       double             t_elapsed;
       double             t_execution;
    
       /* Desired Delta time */
       dt = (t_SimTime - t_previousSimTime)*(scaleFactor[0]);
    
       /* Get clock time at the beginning of this step*/   
       t_previous = hightimer();
       t_0 = t_previous;
    
       /* Wait to reach the desired time */
       t_execution = t_0-t_x[0];
       while (t_diff < (dt - min(dt,t_execution))) {
           t_current = hightimer();
           /* Look for wrapup */
           if (t_current<t_previous){
               t_elapsed = t_previous - t_0;
               t_0 = hightimer() - t_elapsed;
           }
           t_diff = t_current - t_0;
           t_previous = t_current;
       }
    
       /* Store current time to be used in next time step*/
       t_y[0] = dt - t_execution;
       t_x[0] = t_previous;
       ssSetRWorkValue(S,0,t_SimTime);
    }
    
    static void mdlTerminate(SimStruct *S)
    {
        UNUSED_ARG(S); /* unused input argument */
    }
    
    /* Required S-function trailer */
    #ifdef  MATLAB_MEX_FILE    /* Is this file being compiled as a MEX-file? */
    #include "simulink.c"      /* MEX-file interface mechanism */
    #else
    #include "cg_sfun.h"       /* Code generation registration function */
    #endif
    

    I didn't write this file myself, and neither I have a clue what's wrong with it.