n° 219
Novembre 2017
Dicembre 13, 2017, 05:08:14 *
Benvenuto! Accedi o registrati.
Hai dimenticato l'e-mail di attivazione?

Accesso con nome utente, password e durata della sessione
Notizia:
 
   Indice   Linux Windows Techassistance Gameassistance videogame hardware Aiuto Ricerca Agenda Downloads Accedi Registrati  


* Messaggi recenti
Messaggi recenti
Pagine: [1]   Vai giù
  Stampa  
Autore Discussione: typedef di puntatori a funzioni  (Letto 3716 volte)
0 utenti e 1 Utente non registrato stanno visualizzando questa discussione.
c0m0
Newbie
*

Karma: +0/-0
Scollegato Scollegato

Messaggi: 3


Mostra profilo E-mail
« inserita:: Marzo 14, 2013, 08:28:27 »

Ciao a tutti

Uso Linux sul mio PC e sto provando a imparare a programmare, quindi chiedo venia se faccio una domanda stupida, allora questo è il mio piccolo programma che come vediamo non fa un gran che
Codice:
#include <stdio.h>
#include <stdlib.h>


typedef (*handle_t)(const char *name);

typedef struct name {
        handle_t handle;
} name_t;

void print_f(const char *name);
name_t *p = NULL;


int main()
{
        p = malloc(sizeof(name_t));
        p->handle = print_f;
        printf("\t%s\n",p->handle("pippo"));
}

void print_f(const char *name)
{
        printf("\tHello World - %s\n",name);
}

Ma quando compilo il programma con gcc -o pointerfunc pointerfunc.c -g e lo esseguo, mi da questo errore


gdb -q ./pointerfunc
Reading symbols from /export/home/seguraem/C_prog/pointerfunc...done.
(gdb) run
Starting program: /export/home/seguraem/C_prog/pointerfunc
   Hello World - pippo

Program received signal SIGSEGV, Segmentation fault.
__strlen_ia32 () at ../sysdeps/i386/i686/multiarch/../../i586/strlen.S:56
56   ../sysdeps/i386/i686/multiarch/../../i586/strlen.S: No such file or directory.
   in ../sysdeps/i386/i686/multiarch/../../i586/strlen.S
Current language:  auto
The current source language is "auto; currently asm".

(gdb) info frame
Stack level 0, frame at 0xbfffec7c:
 eip = 0xb7ef71ff in __strlen_ia32 (../sysdeps/i386/i686/multiarch/../../i586/strlen.S:56); saved eip 0xb7ec486f
 called by frame at 0xbffff228
 source language asm.
 Arglist at 0xbfffec74, args:
 Locals at 0xbfffec74, Previous frame's sp is 0xbfffec7c
 Saved registers:
  eip at 0xbfffec78

gdb) x/s 0xb7ec486f
0xb7ec486f <_IO_vfprintf_internal+15247>:    "\213\225\210\372\377\377DžD\373\377\377"


Grazie
Registrato
M.A.W. 1968
** LEGGETE IL REGOLAMENTO ! **
Global Moderator
Hero Member
*****

Karma: +224/-19
Scollegato Scollegato

Messaggi: 2988


Discrete And Combinatorial Mathematics


Mostra profilo WWW
« Risposta #1 inserita:: Marzo 14, 2013, 11:31:14 »

L'errore è alquanto ovvio: la sintassi usata nella typedef è erronea e non è supportata.

Ecco invece un ottimo esempio di sintassi corretta, chiara e molto comoda:
Codice:
typedef int (*fptr)(const void*, const void*);
...
static int sort_by_CO(const ranks_t *a, const ranks_t *b)
{
    return (a->CO - b->CO);
}
...
    qsort(bla bla bla..., (fptr)sort_by_CO);

E quindi sarà anche
Codice:
typedef void (*handle_t)(const char *name);
...
void print_f(const char *name)
{
        printf("\tHello World - %s\n",name);
}
Registrato

I Moderatori invitano tutti gli utenti a prendere visione del REGOLAMENTO e a rispettarlo.

Un blog? Io? Occhiolino
c0m0
Newbie
*

Karma: +0/-0
Scollegato Scollegato

Messaggi: 3


Mostra profilo E-mail
« Risposta #2 inserita:: Marzo 15, 2013, 11:03:55 »

Ciao

Non sono un programmatore, ma ho fatto una piccola prova e non mi sembra che il problema sia nell typedef

Se uso il codice in questo modo non da problemi

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

typedef (*handle_t)(char *name);

typedef struct name {
        handle_t handle;
} name_t;

void print_f(const char *name);
name_t *p = NULL;


int main()
{
        p = malloc(sizeof(name_t));
        p->handle = print_f;
        p->handle("pippo");
}

void print_f(const char *name)
{
        printf("\tHello World - %s\n",name);
}


Inveci usando il printf va in error


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



typedef (*handle_t)(char *name);

typedef struct name {
        handle_t handle;
} name_t;

void print_f(const char *name);
name_t *p = NULL;


int main()
{
        p = malloc(sizeof(name_t));
        p->handle = print_f;
        p->handle("pippo");
        printf("\tHello World - %s\n",p->handle("pippo"));
}

void print_f(const char *name)
{
        printf("\tHello World - %s\n",name);
}


A quanto ho capito nella mia ingnoranza, sto usando il printf in modo svagliato, ma la cosa che mi preocupa è il fatto che invece di printare Hello World - Hello World - pippo, va in crash

Grazie 1000
Registrato
M.A.W. 1968
** LEGGETE IL REGOLAMENTO ! **
Global Moderator
Hero Member
*****

Karma: +224/-19
Scollegato Scollegato

Messaggi: 2988


Discrete And Combinatorial Mathematics


Mostra profilo WWW
« Risposta #3 inserita:: Marzo 15, 2013, 04:36:22 »

Non sono un programmatore, ma ho fatto una piccola prova e non mi sembra che il problema sia nell typedef

Questo conferma solo che non sei un programmatore (e che usi un compilatore troppo compiacente con certi tipi di errore). La typedef è formalmente errata, perché non specifica il tipo di ritorno della funzione. I diversi standard prevedono reazioni diverse a questo tipo di comportamento, e in generale, per evitare problemi, è assolutamente opportuno adottare la sintassi esplicita sopra suggerita.

Inoltre il valore di ritorno è ancora causa dei tuoi ulteriori problemi, per il modo incoerente ed errato nel quale utilizzi il puntatore a funzione. La printf si attende un puntatore a char in quel punto, avendo il template %s; ma la tua funzione, lungi dal restituire un puntatore a char, restituisce nulla, essendo dichiarata void.

Devi quindi decidere come impiegherai tale funzione, e modificarla di conseguenza. Se non occorre restituire un valore, come sembra, va benissimo void: ma in tal caso è impossibile richiamarla entro una printf o qualsiasi altra funzione che si attenda di sfruttarne un inesistente valore restituito. In C è sempre e comunque possibile forzare la valutazione di una funzione, anche void,  e sfruttarne così eventuali side effects: entro una comma-separated list, che può essere inserita in praticamente qualsiasi altro contesto sintattico.


Domanda di prammatica: su quale manuale stai studiando il linguaggio C?
Registrato

I Moderatori invitano tutti gli utenti a prendere visione del REGOLAMENTO e a rispettarlo.

Un blog? Io? Occhiolino
c0m0
Newbie
*

Karma: +0/-0
Scollegato Scollegato

Messaggi: 3


Mostra profilo E-mail
« Risposta #4 inserita:: Marzo 15, 2013, 05:17:19 »

Grazie 1000

La tua risposta mi stato molto utile, comunque per adesso non ho letto nessun libro, solo lettura in rete, comunque adesso mi guardo i manuali del link che hai postato

Grazie 1000
Registrato
Pagine: [1]   Vai su
  Stampa  
 
Vai a:  

Copyright © 2017 Edizioni Master SpA. p.iva : 02105820787

Tutti i diritti di proprietà letteraria e artistica riservati. - Privacy



powered by Simple Machines