error C2275: uso ilegal de este tipo como expresión

4 minutos de lectura

Desde ayer, he estado enfrentando un error de compilación para mi proyecto C. El proyecto en sí consiste en crear un servicio que realizará algunas tareas.

No sé qué ha cambiado desde ayer, pero esta mañana, mi código ya no puede compilarse.

Aquí están los errores que tengo:

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

Aquí está el código afectado por estos errores (de las líneas 45 a 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;
}

Y aquí está el código de mi función ServiceMain:

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

No pude encontrar algunas respuestas que se ajusten a mi problema, ¿alguien podría ayudarme? Gracias !

avatar de usuario
rubenvb

Cuando nombras tus archivos fuente *.c, MSVC asume que está compilando C, lo que significa C89. Todas las variables locales de bloque deben declararse al comienzo del bloque.

Las soluciones alternativas incluyen:

  • declarar/inicializar todas las variables locales al comienzo de un bloque de código (directamente después de una llave de apertura) {)
  • cambiar el nombre de los archivos de origen a *.cpp o equivalente y compilar como C++.
  • actualización a VS 2013, que relaja esta restricción.

  • Las declaraciones no necesitan estar al comienzo de un funciónsimplemente necesitan estar al comienzo de un cuadra. Esta: { statement; { declaration; statement; } } es válido incluso en C89/C90.

    –Keith Thompson

    20 de agosto de 2013 a las 15:04

  • Tu primer párrafo todavía necesita arreglo.

    –Keith Thompson

    20 de agosto de 2013 a las 18:37

  • Estoy usando MSVC2013 compilando algunos archivos .C como código C, y sigo recibiendo el error C2275 por mezclar declaraciones e inicializadores. ¿¿Lo que da??

    – Tim Lovell Smith

    30 de diciembre de 2013 a las 19:40

  • Eso fue con la versión 12.0.21005.1 REL en caso de que alguien se pregunte más tarde.

    – Tim Lovell Smith

    30 de diciembre de 2013 a las 21:37

  • Entonces resulta que realmente fue un error, y aparentemente solo sucede cuando aparece la nueva variable después una declaración de bloque sin llaves. Solución alternativa: agregue llaves {} explícitas.

    – Tim Lovell Smith

    31 de diciembre de 2013 a las 6:57


Es posible que esté utilizando una versión de C que no permita declarar variables en medio de un bloque. C solía requerir que las variables se declararan en la parte superior de un bloque, después de la apertura { y antes de las declaraciones ejecutables.

Coloque llaves alrededor del código donde se usa la variable.

En tu caso eso significa:

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

avatar de usuario
laurie stearn

Este error ocurría al transferir un proyecto de una instalación a otra (VS2015 => VS2010).
El código C en realidad se compiló como C++ en la máquina original, en la máquina de destino, la configuración “Predeterminada” en Project Properties\C/C++\Advanced\Compile as de alguna manera apuntaba a C a pesar de que el archivo fuente era del tipo * .cpp.
En mi pequeño programa, aparecieron errores con respecto a la ubicación en el código de ciertos tipos, por ejemplo HWND y HRESULT así como en los diferentes formatos de for loops y construcciones de C++ como LPCTSTR, size_t, StringCbPrintf y BOOL. Comparación.
Cambiando el “Compilar como” de Default para Compile as C++ Code (/TP) lo resolvió

Esto también le dará “uso ilegal de este tipo como expresión”.

INCORRECTO:

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

CORRECTO:

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

Es posible que se pregunte cuál es el punto de ese código. Al convertir explícitamente al tipo que pensé que era, cuando el compilador arrojó un error, me di cuenta de que estaba ignorando una notación húngara delante del nombre de la clase cuando intentaba enviar “esto” al constructor para otro objeto. Cuando busque errores, es mejor probar todas sus suposiciones.

¿Ha sido útil esta solución?

Esta web utiliza cookies propias y de terceros para su correcto funcionamiento y para fines analíticos y para mostrarte publicidad relacionada con sus preferencias en base a un perfil elaborado a partir de tus hábitos de navegación. Al hacer clic en el botón Aceptar, acepta el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos. Configurar y más información
Privacidad