Это - корректный C99, что Вы не должны указывать аргументы в объявлениях указателя функции в структурах?

Я записал, что следующие C99 кодируют, и задавался вопросом об объявлении структуры. В нем я объявляю два указателя функции, которые в конечном счете указывают на два метода нажатия/поп в основном коде. В объявлениях указателя функции я опустил аргументы и компиляции программы хорошо. Это корректно? Я уверен, что считал, что аргументы должны быть предоставлены. Это - корректное поведение C99?

#include 

#define INITIAL_STACK_SIZE 1000

typedef struct stack
{
    int index;
    void *stack[INITIAL_STACK_SIZE];
    void* (*Pop)(); //<-- Is this correct?
    void (*Push)(); //<-- Is this correct?
} stack;

stack CreateStack(void);
void PushStack(stack*, void *);
void *PopStack(stack*);

stack CreateStack(void)
{
    stack s = {0, '\0'};
    s.Pop = PopStack;
    s.Push = PushStack;
    return s;
}

void PushStack(stack *s, void *value)
{
    if(s->index < INITIAL_STACK_SIZE)
    {
        s->stack[s->index++] = value;
    }
    else
    {
        fputs("ERROR: Stack Overflow!\n", stderr);
    }
}

void *PopStack(stack *s)
{
    if(s->index > 0)
    {
        return s->stack[--s->index];
    }
    else
    {
        fputs("ERROR: Stack Empty!\n", stderr);
        return NULL;
    }
}

int main(int argc, char *argv[])
{
    stack s = CreateStack();

    s.Push(&s, "Hello");
    s.Push(&s, "World");

    printf("%s\n", (char*)s.Pop(&s));
    printf("%s\n", (char*)s.Pop(&s));

    return 0;
}

Я пытался добавить аргументы указателям функции, но я получил ошибку компилятора Extraneous old-style parameter list. таким образом, я предполагаю, что это корректно, но любило бы другое мнение.

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

Я использую компилятор C Pelles.

5
задан Gary Willoughby 26 January 2010 в 23:13
поделиться

3 ответа

Хотя он также делает в GCC с STD = C99 -Wall -педантическими , даже не предупреждение об этом, я вообще удивляет его. На мой взгляд, это не довольно круто.

Я считаю, что это гораздо лучшее представление о том, чтобы использовать следующее:

void* (*Pop)(struct stack*);
void (*Push)(struct stack*, void*);

Он делает компиляцию под GCC 4.2 с использованием вышеуказанных переключателей.

В противном случае, глядя на свой код, я мог бы очень хорошо думать, что вы проходите ошибку, позвонив на толчок с двумя аргументами. Вышесказанное также компилируется и очищает эту путаницу.

2
ответ дан 14 December 2019 в 04:38
поделиться

gcc (с -педантик -Wall -std=c99) не имеет проблем с этим кодом:

typedef struct stack
{
 int index;
 void *stack[INITIAL_STACK_SIZE];
 void* (*Pop)(struct stack *);
 void (*Push)(struct stack *, void *);
} stack;
1
ответ дан 14 December 2019 в 04:38
поделиться

, который плохой стиль (хотя и законно). Это будет работать, но это означает, что компилятор не может проверить ваши аргументы. Поэтому, если вы случайно позвоните в такую ​​функцию:

s.Push(arg, &s);   // oops, reverse the arguments

Компилятор не сможет сказать вам, что звонок плохой.

До стандартизации ANSI K & R C не имел прототипов; Он поддерживал только объявления, которые указали тип возврата. Когда вы оставляете аргументы, вы используете эту архаичную функцию.

На GCC вы можете использовать опцию -WSTRICT-прототипы , чтобы включить предупреждения, когда вы их используете.

5
ответ дан 14 December 2019 в 04:38
поделиться
Другие вопросы по тегам:

Похожие вопросы: