Не могу найти мою синтаксическую ошибку, VC++ говорит, что она есть

У меня тут небольшая проблема, я возился с машинным кодом и указателями функций, и есть часть моего кода, которую VC++ просто отказывается компилировать.

Это компилируется и работает точно так, как ожидалось:

#include <stdlib.h>
#include <stdio.h>

int main()
{
    char tarr[] = {0xb8, 222, 0, 0, 0, 0xc3};

    int (*testfn)() = tarr;

    printf("%d", testfn()); // prints 222

    getchar();
}

Однако Visual C++ Express не будет компилировать следующее, что приведет к ошибке: error C2143: syntax error : missing ';' before 'type'

#include <stdlib.h>
#include <stdio.h>

int main()
{
    char* tarr = (char*) malloc(1000);
    tarr[0] = 0xb8;
    tarr[1] = 222;
    tarr[2] = 0;
    tarr[3] = 0;
    tarr[4] = 0;
    tarr[5] = 0xc3;

    int (*testfn)() = tarr; // syntax error here

    printf("%d", testfn());

    getchar();
}

Я просмотрел предположительно ошибочный код и не вижу в нем ничего плохого. В чем дело? Есть что-то, что мне не хватает?


person anonymous coward    schedule 12.02.2010    source источник
comment
с Visual Studio 2008 первая версия не компилируется: ошибка C2440: «инициализация»: невозможно преобразовать из «char [6]» в «int (__cdecl *) (void)»   -  person sergiom    schedule 12.02.2010
comment
@sergiom Это странно - у меня первый фрагмент отлично компилируется в VC++ 2008 Express   -  person anonymous coward    schedule 12.02.2010


Ответы (2)


Это код Си? Если это так, и это не C99, то вам нужно переместить объявление testfd перед присваиванием tarr[X].

person Richard Pennington    schedule 12.02.2010
comment
О, круто, это сработало. Я не знал, что должен был это сделать, поэтому я удивлен, что первый фрагмент скомпилирован. - person anonymous coward; 12.02.2010
comment
Первый фрагмент верен для C ‹ C99. Все объявления в C до C99 должны располагаться перед операторами. - person Richard Pennington; 12.02.2010
comment
На самом деле я не уверен, с каким стандартом C VC++ это компилируется, я точно знаю, что он обрабатывает его как код C, а не C++ - person anonymous coward; 12.02.2010

Код компилируется с предупреждениями в GCC и не компилируется в G++. Вам не хватает актерского состава в этой строке. Вам также не хватает возвращаемого значения из main.

    int (*testfn)() = (int (*)()) tarr; // no more syntax error?
person Draemon    schedule 12.02.2010
comment
Приведение на самом деле не имеет значения, равно как и возвращаемое значение. - person anonymous coward; 12.02.2010
comment
Да, это так: предупреждение существует по какой-то причине. В некоторых архитектурах указатели на функции имеют размер, отличный от указателей на данные. Я всегда компилирую с -Wall. G++ на самом деле называет это ошибкой, поэтому я думаю, что C++ строже, чем C в этом отношении. Это ваша проблема. - person Draemon; 12.02.2010
comment
проблема здесь не только в разных размерах указателя - область памяти, в которой размещается стек и/или куча, может быть дополнительно помечена как неисполняемая - person Christoph; 12.02.2010
comment
А, ну ладно. В моем случае я делаю это как небольшой эксперимент, но я обязательно буду помнить об этом, если мне когда-нибудь понадобится настроить другую архитектуру. - person anonymous coward; 12.02.2010
comment
@Christoph Кристоф Я знаю об этом - я все равно отключил поддержку NX и т. Д. Для этого проекта. - person anonymous coward; 12.02.2010