Path: utzoo!utgpu!jarvis.csri.toronto.edu!rutgers!rochester!cornell!uw-beaver!uw-june!pardo From: pardo@june.cs.washington.edu (David Keppel) Newsgroups: comp.std.c Subject: Re: const in latest draft Message-ID: <8408@june.cs.washington.edu> Date: 1 Jun 89 01:22:43 GMT References: <16259@gryphon.COM> Reply-To: pardo@cs.washington.edu (David Keppel) Organization: U of Washington, Computer Science, Seattle Lines: 82 In article <16259@gryphon.COM> sarima@gryphon.COM (Stan Friesen) writes: >[Discussion of `const' qualifier] I posted a related question about this a while back. I kept the e-mail that I exchanged, in the hope that it would make sense eventually. I've sat on this for a while and I'm still not sure that I understand. Here goes again: I declare a function parameter such as is used by qsort. Unlike qsort, I don't in general require that the function have no side effects, but do want to be able to pass functions that don't have side effects. My understanding of the `const' qualifier is that, when applied to the object type of a pointer function parameter, the function guarantees that it will not change the storage being pointed to. int blah (void const *zork); Says that `blah' will not change whatever `zork' points to. I declare some functions. typedef int (*functype) (void *object); typedef int (*c_functype) (void const *const_object); void toplevel (functype); functype f1; c_functype f2; Calling the parameter functions directly works as expected. const void *object = POINTER_TO_VOID; const void *c_object = POINTER_TO_CONST_VOID; (*f1) (object); /* OK */ (*f2) (object); /* OK */ (*f1) (c_object); /* ERROR */ (*f2) (c_object); /* OK */ Basically, any place that `f1' appears in the code, I can replace it with a call to `f2'. Calling the parameter functions indirectly does not do what I expect. void toplevel (functype f) { (*f)(object); } : : toplevel (f1); /* OK */ toplevel (f2); /* ERROR */ I expect that when the second call will be OK, because I'm passing in a function that guarantees that it won't change its parameters. That function is being used to replace a function that might change its parameters, so the replacement won't do anything that the original couldn't do. Surely there's nothing wrong with that!? Still, I get a `argument passing between incompatible pointer types' type clash warning message from my friendly local dpANS-conformant compiler. According to a clip of the May '88 draft that somebody mailed me (Section 3.5.4.2): For two function types to be compatible, both shall specify compatible return types. Moreover, the parameter type lists, if both are present, shall agree in the number of parameters [...]; corresponding parameters shall have compatible types [...] For each parameter declared with qualified type, its type for these comparisons is the unqualified [Emph. mine] version of it's declared type. So what's my compiler doing? Is this a bug or a feature? Insight is appreciated. ;-D on ( Promotion rules? *Surfing* rules! ) Pardo -- pardo@cs.washington.edu {rutgers,cornell,ucsd,ubc-cs,tektronix}!uw-beaver!june!pardo