c++cvisual-studiowindows-ce

C/C++ C4047 differs in levels of indirection from 'int'?


So I am attempting to compile SQLite (using a different Target Device then is usually used) and I am getting a weird warning and error and I'm not sure what it means for how to fix it. Here is the message I get after I attempt to compile from within Visual Studio:

4>Compiling...
4>interop.c
4> sqlite3.c(11857) : error C2220: warning treated as error - no 'object' file generated
4> sqlite3.c(11857) : warning C4013: 'localtime' undefined; assuming extern returning int
4> sqlite3.c(11857) : warning C4047: '=' : 'tm *' differs in levels of indirection from 'int'
4> sqlite3.c(28379) : error C2040: 'localtime' : 'tm *(const time_t *)' differs in levels of indirection from 'int ()'

And here is the code on those lines:

#else
{
    struct tm *pTm;
    sqlite3_mutex_enter(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER))
    pTm = localtime(&t);                                //Line 11857
    y.Y = pTm->tm_year + 1900;                          
    y.M = pTm->tm_mon + 1;                              
    y.D = pTm->tm_mday;                                 
    y.h = pTm->tm_hour;                                 
    y.m = pTm->tm_min;                                  
    y.s = pTm->tm_sec;                                  
    sqlite3_mutex_leave(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER));
}
#endif

And the method definition for localtime() where it complains about line 28379 and the indirection:

/*************************************************************************
** This section contains code for WinCE only.
*/
/*
** WindowsCE does not have a localtime() function.  So create a
** substitute.
*/
struct tm *__cdecl localtime(const time_t *t)                
{                                                               // Line 28379
  static struct tm y;
  FILETIME uTm, lTm;
  SYSTEMTIME pTm;
  sqlite3_int64 t64;
  t64 = *t;
  t64 = (t64 + 11644473600)*10000000;
  uTm.dwLowDateTime = (DWORD)(t64 & 0xFFFFFFFF);
  uTm.dwHighDateTime= (DWORD)(t64 >> 32);
  FileTimeToLocalFileTime(&uTm,&lTm);
  FileTimeToSystemTime(&lTm,&pTm);
  y.tm_year = pTm.wYear - 1900;
  y.tm_mon = pTm.wMonth - 1;
  y.tm_wday = pTm.wDayOfWeek;
  y.tm_mday = pTm.wDay;
  y.tm_hour = pTm.wHour;
  y.tm_min = pTm.wMinute;
  y.tm_sec = pTm.wSecond;
  return &y;
}

EDIT Here is the struct definition too:

struct tm {
    int tm_sec;     /* seconds after the minute - [0,59] */
    int tm_min;     /* minutes after the hour - [0,59] */
    int tm_hour;    /* hours since midnight - [0,23] */
    int tm_mday;    /* day of the month - [1,31] */
    int tm_mon;     /* months since January - [0,11] */
    int tm_year;    /* years since 1900 */
    int tm_wday;    /* days since Sunday - [0,6] */
    int tm_yday;    /* days since January 1 - [0,365] */
    int tm_isdst;   /* daylight savings time flag */
};

I really haven't been able to figure out what "'tm*' differs in levels of indirection from 'int'" means or how to fix it, I'm not even really sure what the issue is since this compiles for Win32 but not for WinCE.

Does anyone have any insight into the warning\error or how to fix it? Any help is greatly appreciated!

Thanks!


Solution

  • The declaration of your localtime function is not available at the point it is being used. Under C rules, the compiler therefore assumes it's an unknown function returning an int. It then warns about converting that int to a tm* (that's what the "levels of indirection" thing is about).

    The solution is to declare localtime somewhere so that the compiler can see it when compiling sqlite3.c, like in a header file included from that file.

    The second "levels of indirection" message (the error) seems to be because you are defining localtime after it was used, so the compiler already has guessed the signature to have an int return type, and your actual signature differs from that.

    Make sure a correct declaration of localtime is available before the point where it is used. Simply put, you need to place the line

    struct tm *__cdecl localtime(const time_t *t);
    

    somewhere before line 11857. You can put the definition (the function body) wherever you want, just make sure the declaration (the function signature) is known before the function is used anywhere.