ошибка C2275: незаконное использование этого типа в качестве выражения - PullRequest
54 голосов
/ 28 марта 2012

Со вчерашнего дня я столкнулся с ошибкой компиляции для моего C-проекта. Сам проект состоит в создании сервиса, который будет выполнять некоторые задачи.

Я не знаю, что изменилось со вчерашнего дня, но сегодня утром мой код больше не может компилироваться.

Вот ошибки, которые у меня есть:

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

Вот код, связанный с этими ошибками (от 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;
}

А вот код моей функции 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);
}

Мне не удалось найти ответы, подходящие для моей проблемы, кто-нибудь может помочь? Спасибо!

Ответы [ 5 ]

135 голосов
/ 28 марта 2012

Когда вы называете ваши исходные файлы *.c, MSVC предполагает, что компилирует C, что означает C89.Все локальные переменные блока должны быть объявлены в начале блока.

Обходные пути включают в себя:

  • объявление / инициализация всех локальных переменных в начале блока кода (непосредственно послеоткрывающая скобка {)
  • переименовывает исходные файлы в *.cpp или эквивалентный и компилирует в C ++.
  • , обновляя до VS 2013, что ослабляет это ограничение .
7 голосов
/ 28 марта 2012

Возможно, вы используете версию C, которая не позволяет объявлять переменные в середине блока. В C требовалось, чтобы переменные объявлялись в верхней части блока после открытия {и перед исполняемыми операторами.

2 голосов
/ 15 октября 2015

Эта ошибка произошла при переносе проекта из одной установки в другую (VS2015 => VS2010).
Код C фактически был скомпилирован как C ++ на исходном компьютере, на целевом компьютере параметр "По умолчанию" в Project Properties\C/C++\Advanced\Compile as как-то указывал на C, хотя исходный файл имел тип * .cpp.
В моей маленькой программе возникли ошибки, связанные с размещением в коде определенных типов, например, HWND и HRESULT, а также вдругой формат циклов for и конструкции C ++, такие как LPCTSTR, size_t, StringCbPrintf и BOOL. Сравнение .
Изменение «Скомпилировать как» с Default на Compile as C++ Code (/TP) разрешило его.

2 голосов
/ 20 августа 2013

Поставьте скобки вокруг кода, где используется переменная.

В вашем случае это означает:

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);
}
0 голосов
/ 10 февраля 2018

Это также даст вам «незаконное использование этого типа в качестве выражения».

НЕПРАВИЛЬНО:

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

ПРАВИЛЬНО:

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

Возможно, вас интересует смысл этого кода.Явно приведя к типу, который, как мне показалось, был, когда компилятор выдал ошибку, я понял, что игнорирую некоторые венгерские нотации перед именем класса, когда пытаюсь отправить «this» в конструктор для другого объекта.При поиске ошибок лучше всего проверить все свои предположения.

...