简体   繁体   中英

error C2275 : illegal use of this type as an expression

Since yesterday, I've been facing a compiling error for my C project. The project itself consists on creating a service that will make some tasks.

I don't what has changed since yesterday, but this morning, my code can't compile anymore.

Here are the errors I have :

c:\path\main.c(56): error C2275: 'SERVICE_TABLE_ENTRY' : illegal use of this type as an expression
c:\program files\microsoft sdks\windows\v7.0a\include\winsvc.h(773) : see declaration of 'SERVICE_TABLE_ENTRY'
c:\path\main.c(56): error C2146: syntax error : missing ';' before identifier 'DispatchTable'
c:\path\main.c(56): error C2065: 'DispatchTable' : undeclared identifier
c:\path\main.c(56): error C2059: syntax error : ']'
c:\path\main.c(57): error C2065: 'DispatchTable' : undeclared identifier
c:\path\main.c(57): warning C4047: 'function' : 'const SERVICE_TABLE_ENTRYA *' differs in levels of indirection from 'int'
c:\path\main.c(57): warning C4024: 'StartServiceCtrlDispatcherA' : different types for formal and actual parameter 1

Here's the code concerned by these errors (from lines 45 to 58) :

int main(int ac, char *av[])
{
    if (ac > 1)
    {
        if (!parse_args(ac, av))
        {
        aff_error(ARGUMENTS);
        return EXIT_FAILURE;
        }
    }
    SERVICE_TABLE_ENTRY DispatchTable[] = {{MY_SERVICE_NAME, ServiceMain}, {NULL, NULL}};
    StartServiceCtrlDispatcher(DispatchTable);
    return EXIT_SUCCESS;
}

And here's the code of my ServiceMain function :

void WINAPI ServiceMain(DWORD ac, LPTSTR *av)
{
    gl_ServiceStatus.dwServiceType = SERVICE_WIN32;
    gl_ServiceStatus.dwCurrentState = SERVICE_START_PENDING;
    gl_ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP;
    gl_ServiceStatus.dwWin32ExitCode = 0;
    gl_ServiceStatus.dwServiceSpecificExitCode = 0;
    gl_ServiceStatus.dwCheckPoint = 0;
    gl_ServiceStatus.dwWaitHint = 0;
    gl_ServiceStatusHandle = RegisterServiceCtrlHandler(MY_SERVICE_NAME, ServiceCtrlHandler);
    if (gl_ServiceStatusHandle == (SERVICE_STATUS_HANDLE)0)
        return;
    gl_ServiceStatus.dwCurrentState = SERVICE_RUNNING;
    gl_ServiceStatus.dwCheckPoint = 0;
    gl_ServiceStatus.dwWaitHint = 0;
    SetServiceStatus(gl_ServiceStatusHandle, &gl_ServiceStatus);
}

I couldn't manage to find some answers that fit my problem, could anyone helps ? Thanks !

When you name your source files *.c , MSVC assumes it's compiling C, which means C89. All block-local variables need to be declared at the beginning of the block.

Workarounds include:

  • declaring/initializing all local variables at the beginning of a code block (directly after an opening brace { )
  • rename the source files to *.cpp or equivalent and compile as C++.
  • upgrading to VS 2013, which relaxes this restriction .

You might be using a version of C that doesn't allow variables to be declared in the middle of a block. C used to require that variables be declared at the top of a block, after the opening { and before executable statements.

Put braces around the code where the variable is used.

In your case that means:

if (ac > 1)
{
    if (!parse_args(ac, av))
    {
        aff_error(ARGUMENTS);
        return EXIT_FAILURE;
    }
}
{
    SERVICE_TABLE_ENTRY DispatchTable[] = {{MY_SERVICE_NAME, ServiceMain}, {NULL, NULL}};
    StartServiceCtrlDispatcher(DispatchTable);
}

This error occurred when transferring a project from one installation to another (VS2015 => VS2010).
The C code was actually compiled as C++ on the original machine, on the target machine the "Default" setting in Project Properties\\C/C++\\Advanced\\Compile as was somehow pointing to C even though the source file was of type *.cpp.
In my small program, errors popped up regarding the placement in code of certain types eg HWND and HRESULT as well as on the different format of for loops , and C++ constructs like LPCTSTR, size_t , StringCbPrintf and BOOL . Comparison .
Changing the "Compile as" from Default to Compile as C++ Code (/TP) resolved it.

This will also give you "illegal use of this type as an expression".

WRONG:

MyClass::MyClass()
{
   *MyClass _self = this;
}

CORRECT:

MyClass::MyClass()
{
   MyClass* _self = this;
}

You might be wonder the point of that code. By explicitly casting to the type I thought it was, when the compiler threw an error, I realized I was ignoring some hungarian notation in front of the class name when trying to send "this" to the constructor for another object. When bug hunting, best to test all of your assumptions.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM