error C2275 : illegal use of this type as an expression

CVisual Studio-2010WinapiServiceCompiler Errors

C Problem Overview


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 !

C Solutions


Solution 1 - C

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.

Solution 2 - C

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.

Solution 3 - C

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);
}

Solution 4 - C

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 e.g. HWND and HRESULT as well as on the different format of for loops , and C++ constructs like LPCTSTR, size_t, StringCbPrintf and BOOL. [Comparison][1].
Changing the "Compile as" from Default to Compile as C++ Code (/TP) resolved it.

[1]: http://www.cprogramming.com/tutorial/c-vs-c++.html "Comparison"

Solution 5 - C

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.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionB FView Question on Stackoverflow
Solution 1 - CrubenvbView Answer on Stackoverflow
Solution 2 - CWindows programmerView Answer on Stackoverflow
Solution 3 - Cuser1130406View Answer on Stackoverflow
Solution 4 - CLaurie StearnView Answer on Stackoverflow
Solution 5 - CKANJICODERView Answer on Stackoverflow