函数'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 <windows.h>
(由于 #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'的隐式声明的主要内容,如果未能解决你的问题,请参考以下文章