简体   繁体   English

是否正确C99,您不需要在结构中的函数指针声明中指定参数?

[英]Is it correct C99 that you don't need to specify arguments in function pointer declarations in structs?

I have written the following C99 code and was wondering about the struct declaration. 我编写了以下C99代码,并对结构声明感到疑惑。 In it i declare two function pointers which ultimately point to the two push/pop methods in the main code. 在其中我声明了两个函数指针,它们最终指向主代码中的两个push / pop方法。 In the function pointer declarations i've ommited the arguments and the program compiles ok. 在函数指针声明中,我已经省略了参数,程序编译好了。 Is this correct? 它是否正确? I'm sure i've read that the arguments must be supplied. 我确定我已经读过必须提供的论据。 Is this correct C99 behaviour? 这是正确的C99行为吗?

#include <stdio.h>

#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;
}

I tried adding the arguments to the function pointers but i got a compiler error of Extraneous old-style parameter list. 我尝试将参数添加到函数指针但是我得到了Extraneous old-style parameter list.的编译器错误Extraneous old-style parameter list. so i'm guessing it's correct, but would love another opinion. 所以我猜它是正确的,但会喜欢另一种意见。

EDIT: I was experiencing the above 'Extraneous old-style parameter list' error because i was using the typedef name 'stack' rather than using the struct keyword with 'stack' to define it was the structure i am currently defining. 编辑:我遇到了上述“无关的旧式参数列表”错误,因为我使用的是typedef名称'stack',而不是使用带有'stack'的struct关键字来定义它是我当前定义的结构。

I'm using the Pelles C compiler. 我正在使用Pelles C编译器。

That is bad style (although legal). 这是不好的风格(虽然合法)。 It will work but it means the compiler can't check your arguments. 它会工作,但这意味着编译器无法检查您的参数。 So if you accidentally call your function like this: 所以,如果你不小心打电话给你的功能:

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

the compiler won't be able to tell you the call is bad. 编译器将无法告诉您通话不好。

Prior to ANSI standardization, K&R C did not have prototypes; 在ANSI标准化之前,K&R C没有原型; it only supported declarations that specified the return type. 它只支持指定返回类型的声明。 When you leave out the arguments, you are using this archaic feature. 当你省略参数时,你正在使用这个古老的功能。

On gcc, you can use the option -Wstrict-prototypes to enable warnings when you use them. 在gcc上,您可以使用选项-Wstrict-prototypes在使用它们时启用警告。

Though it also does under GCC with std=c99 -Wall -pedantic without even a warning about it, I'm surprised it compiles at all. 虽然它也在GCC下使用std=c99 -Wall -pedantic ,甚至没有警告它,但我很惊讶它编译完全。 In my opinion, that's not pretty cool. 在我看来,这不是很酷。

I believe it's a much better idea to use the following: 我相信使用以下内容会更好一点:

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

It does compile under GCC 4.2 using the above switches. 它使用上述开关在GCC 4.2下编译。

Otherwise, looking at your code, I could very well think you're doing a mistake by calling Push with two arguments. 否则,看看你的代码,我很可能会认为你用两个参数调用Push会犯一个错误。 The above also compiles and clears that confusion. 以上也编译并清除了这种混乱。

gcc (with -pedantic -Wall -std=c99 ) has no problem with this code: gcc(使用-pedantic -Wall -std=c99 )对此代码没有问题:

typedef struct stack
{
 int index;
 void *stack[INITIAL_STACK_SIZE];
 void* (*Pop)(struct stack *);
 void (*Push)(struct stack *, void *);
} stack;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM