drh@romeo.cs.duke.edu (D. Richard Hipp) (04/10/90)
In article <6090.2621f6c2@csv.viccol.edu.au> timcc@csv.viccol.edu.au writes: >struct foo { > char *name ; > int (*function) () ; > } ; > >struct foo foo_table[] = { > "bar", (int * ()) bar, > "blurfl", (int * ()) blurfl, > "frobjitz", (int * ()) frobjitz, > } ; The typecast (int *()) is for "function returning pointer to integer". To get "pointer to function returning integer" use (int (*)()). The rule is this: operators on the right hand side bind tighter than operators on the left hand side. Thus "()" binds tighter than "*". You want the "*" to bind closest, so the extra parenthesis are required.
timcc@csv.viccol.edu.au (04/11/90)
Given the following C source: extern void bar () ; extern void blurfl () ; extern void frobjitz () ; struct foo { char *name ; int (*function) () ; } ; struct foo foo_table[] = { "bar", (int * ()) bar, "blurfl", (int * ()) blurfl, "frobjitz", (int * ()) frobjitz, } ; I get the following errors from GNU C, version 1.36: above_source:11: conversion to non-scalar type requested above_source:12: conversion to non-scalar type requested above_source:13: conversion to non-scalar type requested So how do I cast to "pointer to function returning int" ? -- Tim Cook Systems Administrator, Victoria College Computer Services parrot - n. An animal that has the ability to imitate man, but not the intelligence to refrain from doing so.
CMH117@psuvm.psu.edu (Charles Hannum) (04/11/90)
In article <6090.2621f6c2@csv.viccol.edu.au>, timcc@csv.viccol.edu.au says: > >So how do I cast to "pointer to function returning int" ? Get yourself a copy of cdecl. Then: cdecl Type "help" or "?" for help. cdecl> cast foo into pointer to function returning int (int (*)())foo cdecl> quit IMHO, anyone who doesn't use cdecl is crazy. BTW: Casting a void function to an int function is extremely non-portable. Virtually, - Charles Martin Hannum II "Klein bottle for sale ... inquire within." (That's Charles to you!) "To life immortal!" cmh117@psuvm.{bitnet,psu.edu} "No noozzzz izzz netzzzsnoozzzzz..." c9h@psuecl.{bitnet,psu.edu} "Mem'ry, all alone in the moonlight ..."
martin@mwtech.UUCP (Martin Weitzel) (04/11/90)
In article <18834@duke.cs.duke.edu> drh@romeo.UUCP (D. Richard Hipp) writes: :In article <6090.2621f6c2@csv.viccol.edu.au> timcc@csv.viccol.edu.au writes: :>struct foo { :> char *name ; :> int (*function) () ; :> } ; :> :>struct foo foo_table[] = { :> "bar", (int * ()) bar, :> "blurfl", (int * ()) blurfl, :> "frobjitz", (int * ()) frobjitz, :> } ; : :The typecast (int *()) is for "function returning pointer to integer". :To get "pointer to function returning integer" use (int (*)()). : :The rule is this: operators on the right hand side bind tighter than :operators on the left hand side. Thus "()" binds tighter than "*". :You want the "*" to bind closest, so the extra parenthesis are required. Or, if you want an easy 'step-to-step' procedure, do it as follows: 1) write a declaration for some object 'foo', so that 'foo' has the desired type. 2) avoid all unnecessary brackets (here the above rule comes into play, that '()' and '[]' on the right bind more tightly than '*' on the left; use brackets like in expressions, if you want other binding) 3) cancel the name 'foo' and enclose what remains in brackets 4) after half an hour take the freshly baked cast out of the oven and enjoy! -- Martin Weitzel, email: martin@mwtech.UUCP, voice: 49-(0)6151-6 56 83
martin@mwtech.UUCP (Martin Weitzel) (04/11/90)
In article <90100.172535CMH117@psuvm.psu.edu> CMH117@psuvm.psu.edu (Charles Hannum) writes: [some lines deleted] > >IMHO, anyone who doesn't use cdecl is crazy. very small flame (no, not really a flame) IMHO, better try to *understand* how it must be done. Before the age of electronic pocket calculators (oh, can you imangine, these little things were not allways around since God created the world), people used to know that, say 12.5 percent from $18.60 must be roughly around $2.00 - today they happily use their pocket calculator and will accept every answer between $0.02 (the smallest coin in their cash register) or $200.00 (because that's the maximum amount, they are allowed to pay to you without notifying their boss). Just a story, ehhm, yes kkkkeys bounce somettttimes. -- Martin Weitzel, email: martin@mwtech.UUCP, voice: 49-(0)6151-6 56 83
williamt@athena1.Sun.COM (William A. Turnbow) (04/11/90)
Where can one get a copy of cdecl? -wat- --- An it harm none, do what you will. *** America vs. developed country rankings: chemistry 11/13, physics 9/13 biology 13/13, infant mortality 1/13, teen pregnancy 1/13
cml@tove.umd.edu (Christopher Lott) (04/11/90)
In article <134288@sun.Eng.Sun.COM> williamt@sun.UUCP (William A. Turnbow) writes: > Where can one get a copy of cdecl? I posted this info about a month ago. Brief recap: cdecl is available for anonymous ftp from mimsy.umd.edu as "cdecl.shar" The local name server tells me this about mimsy: mimsy.umd.edu 432000 IN A 128.8.128.8 Desperate uucp sites can email me for a copy. chris... -- cml@tove.umd.edu Dept. of Computer Science, U. Maryland at College Park 4122 A.V.Williams 301-454-8711 <standard disclaimers>
mcdaniel@amara.uucp (Tim McDaniel) (04/13/90)
CMH117@psuvm.psu.edu (Charles Hannum) writes: Casting a void function to an int function is extremely non-portable. Not quite. ANSI C, and many existing compilers, requires that function pointers all be the same size. Any pointer to a function can be cast into any other pointer-to-function type and back again, producing the same pointer value. However, the value can't be called while it is cast to a different type. For example: typedef anytype (*PF_ANY )(); typedef othertype (*PF_OTHER)(); /* * PF_ANY is the type "pointer to function () returning anytype". * PF_OTHER is the type "pointer to function () returning othertype". * Assume that anytype and othertype are different types. */ PF_ANY f1, f2; PF_OTHER g; ... g = (PF_OTHER) f1; /* legal under ANSI C */ f2 = (PF_ANY) g; /* legal under ANSI C */ if (f1 != f2) { /* then this compiler is not ANSI C compliant. */ } (*f2)(); /* exact same result as "(*f1)();" */ (*g)(); /* illegal under ANSI C */ And, by the way, f2 = (PF_ANY) (void *) f1; is illegal in ANSI C. "void *" is the universal pointer only for DATA objects, not functions. You can convert any FUNCTION pointer to any other FUNCTION pointer type. To rephrase, then: Casting a pointer to void function to a pointer to int function type, and calling that result, is extremely non-portable. -- Tim McDaniel Applied Dynamics International, Ann Arbor, MI Internet: mcdaniel%amara.uucp@mailgw.cc.umich.edu UUCP: {uunet,sharkey}!amara!mcdaniel