Deutsch English Français Italiano |
<uu6p4t$cm5h$2@dont-email.me> View for Bookmarking (what is this?) Look up another Usenet article |
Path: ...!eternal-september.org!feeder3.eternal-september.org!news.eternal-september.org!.POSTED!not-for-mail From: David Brown <david.brown@hesbynett.no> Newsgroups: comp.lang.c Subject: Re: Casting the return value of ... Date: Fri, 29 Mar 2024 17:10:05 +0100 Organization: A noiseless patient Spider Lines: 104 Message-ID: <uu6p4t$cm5h$2@dont-email.me> References: <uu416t$33u55$1@news.xmission.com> <20240328105203.773@kylheku.com> <87frwatadu.fsf@nosuchdomain.example.com> <uu4k1c$3pq71$1@dont-email.me> <uu6dtk$a076$1@dont-email.me> <uu6fss$agvi$1@dont-email.me> MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 8bit Injection-Date: Fri, 29 Mar 2024 16:10:05 +0100 (CET) Injection-Info: dont-email.me; posting-host="528a481da3bf32c95b1c8190e81e5c9b"; logging-data="415921"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX1+ZVOWdzxCpliOBp2OHJpdY1jQURSiAjF4=" User-Agent: Mozilla Thunderbird Cancel-Lock: sha1:eiHFnK6KBH9fE/IO7NKTNujUBUE= In-Reply-To: <uu6fss$agvi$1@dont-email.me> Content-Language: en-GB Bytes: 4810 On 29/03/2024 14:32, bart wrote: > On 29/03/2024 12:58, David Brown wrote: >> On 28/03/2024 21:30, bart wrote: >>> On 28/03/2024 19:38, Keith Thompson wrote: >>>> Kaz Kylheku <433-929-6894@kylheku.com> writes: >>>> [...] >>>>> Conversions between function pointers and data pointers are an >>>>> extension; it is not well-defined behavior in ISO C. >>>>> >>>>> Therefore we can neither say that ISO C doesn't require a cast >>>>> there (it >>>>> imposes no requirements at all), nor that the conversion is fine >>>>> with a >>>>> cast. >>>>> >>>>> The cast is /likely/ necessary, in order to correctly trigger the >>>>> extension. >>>> >>>> ISO C does require a cast. The cast is necessary to avoid a constraint >>>> violation and a mandatory diagnostic. The resulting behavior is >>>> undefined in ISO C, but defined by POSIX. >>>> >>>> Assigning a void* value to a pointer-to-function object without a cast >>>> violates the constraint for simple assignment (N1570 6.5.16.1p1). >>> >>> What would such a cast look like? Since this gives a warning with >>> -Wpedantic even with a cast: >>> >>> void* p; >>> void(*q)(void); >>> >>> p=(void*)q; >>> q=(void(*)(void))p; >>> >>> >> >> One method that silences all gcc warnings here is to cast via uintptr_t: >> >> #include <stdint.h> >> >> void* p; >> void(*q)(void); >> >> typedef void(*FVoid)(void); >> >> void foo(void) { >> p = (void*) (uintptr_t) q; >> } >> >> void bar(void) { >> q = (FVoid) (uintptr_t) p; >> } > > I was aware of the double conversion but KT used 'a cast' so I wondered > if there was a single cast that could be used. A single cast is all that is needed as far as the C standards are concerned, but the double cast is helpful to silence the gcc warning. (I agree with Keith that a diagnostic is not required by the C standards, and thus the warning message and the choice of flag to control it are inaccurate, but I think it is a useful warning to have enabled in general.) > > It is odd however that function and object pointers can be considered so > different that even an explicit conversion between them is deemed to be > meaningless. > Why? They are such totally different concepts in C. It does not make sense, within the semantics of C, to consider functions as data or data as functions. It can make sense in a wider context, outside of the things defined in the C standards, and it is useful that you can make such conversions with real C compilers (since the C standards don't cover /everything/ of interest to programmers). But it seems very reasonable to me to say that programmers have to go out of their way to mix functions and data like this - it is a good thing that awkward, rare and inherently risky things are harder to write and come with warnings. > Yet converting either to and from an integer type is perfectly fine, > even though it isn't even a pointer type! I'd be happy if C required a bit more effort for converting back and forth between pointers and integer types - the ease here is for historic reasons, I think. But at least it needs a cast. > > I wonder then why a conversion between function and object couldn't be > implemented, internally, via such an intermediate integer type anyway. > I'm sure it could. I don't see such pointer conversions having wide-spread use, and thus don't see any reason to make them easier. Cases such as "dlsym" are rare, and any required ugly conversions can be neatly contained within the function.