web-dev-qa-db-fra.com

erreur C2275: utilisation illégale de ce type en tant qu'expression

Depuis hier, je fais face à une erreur de compilation pour mon projet C. Le projet lui-même consiste à créer un service qui effectuera certaines tâches.

Je ne fais pas ce qui a changé depuis hier, mais ce matin, mon code ne peut plus être compilé.

Voici les erreurs que j'ai:

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

Voici le code concerné par ces erreurs (des lignes 45 à 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;
}

Et voici le code de ma fonction 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);
}

Je n'arrivais pas à trouver des réponses à mon problème, est-ce que quelqu'un pourrait m'aider? Merci !

51
Billy McNuggets

Lorsque vous nommez vos fichiers source *.c, MSVC suppose qu'il compile C, ce qui signifie C89. Toutes les variables de bloc locales doivent être déclarées au début du bloc.

Les solutions incluent:

  • déclaration/initialisation de toutes les variables locales au début d'un bloc de code (directement après une accolade d'ouverture {)
  • renommez les fichiers source en *.cpp ou l’équivalent et compilez-le en C++.
  • la mise à niveau vers VS 2013, ce qui assouplit cette restriction .
131
rubenvb

Vous utilisez peut-être une version de C qui n'autorise pas la déclaration de variables au milieu d'un bloc. C exigeait que les variables soient déclarées au sommet d’un bloc, après l’ouverture {et avant les instructions exécutables.

6
Windows programmer

Cette erreur s'est produite lors du transfert d'un projet d'une installation à une autre (VS2015 => VS2010).
Le code C a en fait été compilé en tant que C++ sur la machine d'origine. Sur la machine cible, le paramètre "Par défaut" dans Project Properties\C/C++\Advanced\Compile as désignait en quelque sorte le C même si le fichier source était de type * .cpp.
Dans mon petit programme, des erreurs sont apparues concernant la mise en code de certains types, par exemple. HWND et HRESULT ainsi que sur le format différent de boucles for et de constructions C++ telles que LPCTSTR,size_t, StringCbPrintf et BOOL. Comparaison
Changer le "Compiler en tant que" de Default à Compile as C++ Code (/TP) l'a résolu.

2
Laurie Stearn

Placez des accolades autour du code où la variable est utilisée.

Dans votre cas, cela signifie:

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

Cela vous donnera également "une utilisation illégale de ce type comme expression".

FAUX:

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

CORRECT:

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

Vous pourriez être demander le point de ce code. En choisissant explicitement le type que je pensais, lorsque le compilateur a lancé une erreur, j'ai réalisé que j'ignorais une notation hongroise devant le nom de la classe lorsque j'essayais d'envoyer "this" Au constructeur pour un autre objet. Lors de la chasse aux bogues, il est préférable de tester toutes vos hypothèses.

0
J.M.I. MADISON