函数'min'的隐式声明

Posted

技术标签:

【中文标题】函数\'min\'的隐式声明【英文标题】:Implicit declaration of function 'min'函数'min'的隐式声明 【发布时间】:2014-01-07 20:06:43 【问题描述】:

我在我的 MacBook 上使用 Matlab R2013b 和 Xcode 5.0.2 来混合一个名为 sfun_rttime.c 的文件,使用 Matlab 的命令:mex sfun_rrtime.c

这会导致以下错误消息:

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.

.c 文件如下所示:

#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

这个文件不是我自己写的,也不知道有什么问题。

【问题讨论】:

@Sourav Ghosh,不知道,在运行 Windows 的另一台计算机上混合此文件没有问题。 C99 中没有 min 函数或宏,fmin 确实存在(如果它们出现,它会正确处理 NaN 值)。请注意,windows.h 定义了自己的最小/最大宏 【参考方案1】:

在非 Windows 机器上,您不使用 #include &lt;windows.h&gt;(由于 #ifdef 和明显的其他原因)。 Windows.h 拉入WinDef.h,而WinDef.h 包含:

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

那是他去的地方!

您可以实现宏,如前所述使用 fmin()(注意当前的 math.h 包含 #ifdef 也已退出),或者如果您感觉真的好心并想要给链接器准确地它在寻找什么:

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

【讨论】:

【参考方案2】:

下面用"double fmin(double x, double y)"代替min怎么样?

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

#include <math.h>
#define min(a,b) fmin(a,b)
...

【讨论】:

Integer 没有方法min,如果使用min(a,b),我会得到同样的错误

以上是关于函数'min'的隐式声明的主要内容,如果未能解决你的问题,请参考以下文章

C中函数的隐式声明

函数“等待”的隐式声明

mkstemp 函数的隐式声明

什么是C语言中的隐式函数声明?

函数‘atoi’的隐式声明?

警告:函数的隐式声明