thorinn@skinfaxe.diku.dk (Lars Henrik Mathiesen) (11/29/90)
ANSI C guarantees that a pointer to a function can be cast to another
function pointer type and back, and retain its value. However, if it
is used ``at a wrong type'', the results are undefined.
My question is: Can a conforming compiler generate a warning for casts
(and arguments) that will ``go wrong'' but not for those that work?
I'm thinking of something like this:
void myqsort(void **, int (*)(void *, void *));
typedef struct { ... } data;
int foo(data * a, data * b) { ... }
int main() {
data *sort[NSORT];
...
myqsort(sort, foo);
...
}
This will work as expected if and only if exactly the same calling
sequence is generated for the following two calls to foo:
void *a, *b;
foo(a, b);
( (void (*)(void *, void *))foo )(a, b);
If it works, the compiler should warn about a non-portable cast; if it
doesn't work, the warning should say 'cast between pointers to
functions with incompatible calling sequences' or something. And the
former might be easier to turn off than the latter.
The questions are: Do any compilers implement this test? Would it be
difficult to do so in, e.g., gcc? And is it legal for a conforming
ANSI C compiler to diagnose only ``bad'' casts?
--
Lars Mathiesen, DIKU, U of Copenhagen, Denmark [uunet!]mcsun!diku!thorinn
Institute of Datalogy -- we're scientists, not engineers. thorinn@diku.dk
gwyn@smoke.brl.mil (Doug Gwyn) (11/30/90)
In article <1990Nov29.110114.21565@diku.dk> thorinn@skinfaxe.diku.dk (Lars Henrik Mathiesen) writes: >My question is: Can a conforming compiler generate a warning for casts >(and arguments) that will ``go wrong'' but not for those that work? A conforming implementation must produce at least one diagnostic for each translation unit that violates a syntax rule or constraint. Diagnostics may be produced under other circumstances, but are not required. In your example, the syntax is presumably correct, so that leaves only the question of whether a constraint is violated. The relevant constraint appears to be in 3.3.2.2 (Function Calls): each argument must be assignment-compatible with the corresponding parameter. This leads us to 3.3.16.1 (Simple Assignment), where the constraints require pointers to compatible types (apart from the qualifiers). That leads to 3.1.2.6 (Compatible Type and Composite Type), which immediately leads to 3.5.4 (Declarators), more specifically 3.5.4.3 (Function Declarators (Including Prototypes)), where inder Semantics we finally find out what is really required: return value and parameters must have compatible types. So, the final constraint to be checked is whether void* and data* are compatible types. This leads us around to 3.5.4.1, which requires that void and data be compatible types. The search ends here, because there is nothing in the standard that says that void is compatible with a structure type. Thus a constraint IS violated, and a diagnostic IS required. The compiler could go ahead and translate the source into object code that might actually work; there is no requirement that a conforming implementation reject programs that generate diagnostics.
manning@nntp-server.caltech.edu (Evan Marshall Manning) (11/30/90)
thorinn@skinfaxe.diku.dk (Lars Henrik Mathiesen) writes: >My question is: Can a conforming compiler generate a warning for casts >(and arguments) that will ``go wrong'' but not for those that work? gwyn@smoke.brl.mil (Doug Gwyn) writes: >A conforming implementation must produce at least one diagnostic for each >translation unit that violates a syntax rule or constraint. Diagnostics >may be produced under other circumstances, but are not required. My favorite lint (from Gimpel) would call those that work "non-portable", and issue a more serious warning/error message for those that not will work. *************************************************************************** Your eyes are weary from staring at the CRT for so | Evan M. Manning long. You feel sleepy. Notice how restful it is | is to watch the cursor blink. Close your eyes. The |manning@gap.cco.caltech.edu opinions stated above are yours. You cannot | manning@mars.jpl.nasa.gov imagine why you ever felt otherwise. | gleeper@tybalt.caltech.edu
thorinn@rimfaxe.diku.dk (Lars Henrik Mathiesen) (12/04/90)
thorinn@skinfaxe.diku.dk (Lars Henrik Mathiesen) writes: >My question is: Can a conforming compiler generate a warning for casts >(and arguments) that will ``go wrong'' but not for those that work? gwyn@smoke.brl.mil (Doug Gwyn) writes: >A conforming implementation must produce at least one diagnostic for each >translation unit that violates a syntax rule or constraint. Diagnostics >may be produced under other circumstances, but are not required. Doug's analysis applies to the "(and arguments)" in the question. For casts, 3.3.4 (Cast operators) Semantics tells us that behaviour is undefined because the function types are incompatible, but no diagnostic is required. manning@nntp-server.caltech.edu (Evan Marshall Manning) writes: >My favorite lint (from Gimpel) would call those that work "non-portable", >and issue a more serious warning/error message for those that not will >work. Is this lint architecture- and compiler-specific (or configurable) since it knows what works? Or does it just guess based on two's complement, byte addressable, 32-bit int and pointer machines? -- Lars Mathiesen, DIKU, U of Copenhagen, Denmark [uunet!]mcsun!diku!thorinn Institute of Datalogy -- we're scientists, not engineers. thorinn@diku.dk
manning@nntp-server.caltech.edu (Evan Marshall Manning) (12/05/90)
thorinn@skinfaxe.diku.dk (Lars Henrik Mathiesen) writes: >My question is: Can a conforming compiler generate a warning for casts >(and arguments) that will ``go wrong'' but not for those that work? I wrote: >My favorite lint (from Gimpel) would call those that work "non-portable", >and issue a more serious warning/error message for those that not will >work. thorinn@skinfaxe.diku.dk (Lars Henrik Mathiesen) writes: >Is this lint architecture- and compiler-specific (or configurable) >since it knows what works? Or does it just guess based on two's >complement, byte addressable, 32-bit int and pointer machines? The Gimpel product I use is for PCs only, so it knows everything about the processor architecture. Various flags tell it sizeof int, data pointers, and function pointers. They're pretty good about providing flags for everything reasonable so I'd bet there are one or two extra flags on their more generic product. *************************************************************************** Your eyes are weary from staring at the CRT for so | Evan M. Manning long. You feel sleepy. Notice how restful it is | is to watch the cursor blink. Close your eyes. The |manning@gap.cco.caltech.edu opinions stated above are yours. You cannot | manning@mars.jpl.nasa.gov imagine why you ever felt otherwise. | gleeper@tybalt.caltech.edu