Я записал, что следующие 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.
Хотя он также делает в GCC с STD = C99 -Wall -педантическими
, даже не предупреждение об этом, я вообще удивляет его. На мой взгляд, это не довольно круто.
Я считаю, что это гораздо лучшее представление о том, чтобы использовать следующее:
void* (*Pop)(struct stack*);
void (*Push)(struct stack*, void*);
Он делает компиляцию под GCC 4.2 с использованием вышеуказанных переключателей.
В противном случае, глядя на свой код, я мог бы очень хорошо думать, что вы проходите ошибку, позвонив на толчок с двумя аргументами. Вышесказанное также компилируется и очищает эту путаницу.
gcc (с -педантик -Wall -std=c99
) не имеет проблем с этим кодом:
typedef struct stack
{
int index;
void *stack[INITIAL_STACK_SIZE];
void* (*Pop)(struct stack *);
void (*Push)(struct stack *, void *);
} stack;
, который плохой стиль (хотя и законно). Это будет работать, но это означает, что компилятор не может проверить ваши аргументы. Поэтому, если вы случайно позвоните в такую функцию:
s.Push(arg, &s); // oops, reverse the arguments
Компилятор не сможет сказать вам, что звонок плохой.
До стандартизации ANSI K & R C не имел прототипов; Он поддерживал только объявления, которые указали тип возврата. Когда вы оставляете аргументы, вы используете эту архаичную функцию.
На GCC вы можете использовать опцию -WSTRICT-прототипы
, чтобы включить предупреждения, когда вы их используете.