È corretto C99 che non è necessario per specificare gli argomenti nelle dichiarazioni puntatore a funzione in struct?

StackOverflow https://stackoverflow.com/questions/2143315

  •  23-09-2019
  •  | 
  •  

Domanda

Ho scritto il seguente codice C99 e si chiedeva circa la dichiarazione di struct. In essa dichiaro due puntatori alle funzioni che in ultima analisi indicano due metodi di spinta / pop nel codice principale. Nelle dichiarazioni puntatore a funzione che ho ommited gli argomenti e il programma viene compilato ok. È corretto? Sono sicuro che ho letto che gli argomenti devono essere forniti. È corretto comportamento 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;
}

Ho provato ad aggiungere gli argomenti per i puntatori a funzione, ma ho ottenuto un errore di compilazione di Extraneous old-style parameter list. quindi immagino che sia corretto, ma mi piacerebbe un altro parere.

EDIT: stavo sperimentando l'errore di cui sopra 'estranea lista dei parametri vecchio stile', perché stavo usando il nome typedef 'pila' piuttosto che utilizzare la parola chiave struct con 'pila' per definirla era la struttura attualmente sto definendo.

Sto utilizzando il Pelles C compilatore.

È stato utile?

Soluzione

Anche se lo fa anche sotto GCC con std=c99 -Wall -pedantic senza nemmeno un avvertimento a questo proposito, sono sorpreso che compila a tutti. A mio parere, questo non è abbastanza freddo.

Credo che sia un'idea molto migliore di utilizzare il seguente:

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

E si compila sotto GCC 4.2 utilizzando parametri sopra.

In caso contrario, guardando il codice, avrei potuto benissimo pensare che stai facendo un errore chiamando Spingere con due argomenti. Quanto sopra compila e cancella quella confusione.

Altri suggerimenti

Questo è un cattivo stile (anche se legale). Essa opererà ma significa il compilatore non può controllare i vostri argomenti. Quindi, se si chiama per sbaglio la funzione in questo modo:

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

il compilatore non sarà in grado di dirvi la chiamata è male.

Prima di ANSI standardizzazione, K & R C non ha avuto prototipi; è supportato solo dichiarazioni che specificano il tipo di ritorno. Quando si lascia fuori gli argomenti, si utilizza questa funzione arcaica.

In gcc, è possibile utilizzare l'opzione per abilitare -Wstrict-prototypes avvisi quando si utilizzano.

gcc (con -pedantic -Wall -std=c99) non ha alcun problema con questo codice:

typedef struct stack
{
 int index;
 void *stack[INITIAL_STACK_SIZE];
 void* (*Pop)(struct stack *);
 void (*Push)(struct stack *, void *);
} stack;
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top