Path: csiph.com!news.swapon.de!eternal-september.org!feeder3.eternal-september.org!news.eternal-september.org!.POSTED!not-for-mail
From: Tim Rentsch
Newsgroups: comp.lang.c++
Subject: Re: Proper cast of function pointers
Date: Thu, 25 Apr 2024 15:04:42 -0700
Organization: A noiseless patient Spider
Lines: 71
Message-ID: <8634r9w139.fsf@linuxsc.com>
References: <86frvawgwj.fsf@linuxsc.com>
MIME-Version: 1.0
Content-Type: text/plain; charset=us-ascii
Injection-Date: Fri, 26 Apr 2024 00:04:45 +0200 (CEST)
Injection-Info: dont-email.me; posting-host="f2bed875c7d47d71c2ee481e5ebd514b"; logging-data="3410014"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX19NkLik2o7DYE+EaoS9dbCPN9C9ag/Hw7g="
User-Agent: Gnus/5.11 (Gnus v5.11) Emacs/22.4 (gnu/linux)
Cancel-Lock: sha1:bdOLnCMkOtf5qW6k8RXuKnUt9qc= sha1:6cbpgdNOt9VGpQeTxWsBoYmPeDA=
Xref: csiph.com comp.lang.c++:118890
Paavo Helde writes:
> 25.04.2024 01:10 Tim Rentsch kirjutas:
>
>> Paavo Helde writes:
>
> [...]
>
>>> static const formu_item ftable_static[TABLESIZE]=
>>> {
>>> {"exp", exp,1,0},
>>> {"ln", log,1,0},
>>> {"sin", sin,1,0},
>>> {"cos", cos,1,0},
>>> {"tan", tan,1,0},
>>> {"asin", asin,1,0},
>>> {"acos", acos,1,0},
>>> {"atan", atan,1,0},
>>> {"atan2", FuncCast2(atan2),2,0},
>>> {"abs", fabs,1,0},
>>> {"sqrt", sqrt,1,0},
>>> {"pi", FuncCast0(pi),0,0},
>>> //...
>>> }
>>
>> The code below uses no casting, and encapsulates the constructors
>> for 'formu_item's so that the functions are guaranteed to be in
>> sync with the discriminating member of the struct. The names and
>> types of members in formu_item have been changed slightly in some
>> cases, but except for that it should drop in to the existing code
>> pretty easily. The final function shows how to invoke a function
>> in the table safely.
>
> Indeed. Somehow I was convinced that when providing multiple
> constructors, the compiler would fail with ambiguity errors because
> all of these functions like sin() are overloaded in C++. But it seems
> the compiler figures it out nicely.
As it turns out I may have complicated the question by using
rather than . However, upon trying again with
and with both and I learned that
overload resolution is indeed smart enough to figure out which
function matches. I expect this works because exact matches
always take precedence.
>> I have added a few bits of running commentary.
>>
>> Code compiles cleanly (if I haven't made any editing mistakes)
>> with -pedantic -Wall -Wextra, under c++11, c++14, and c++17.
>
> This is not exactly true, when compiling with VS2022 I get two compile
> errors:
>
> if (k >= n) return 0. / 0.; // k too large => NaN
>
> 1>C:\Test\ConsoleTestVS2022\ConsoleTest2022\main.cpp(97,18): error
> C2124: divide or mod by zero
How strange. In C it would work (and it does work under gcc
and clang). Apparently the C++ standard is fuzzier about what
is required for floating-point constant expressions.
> But that's fully another topic.
Right. Also I expect the limitation is easy to get around, if
that is important (and here it really wasn't).
> Thanks for the demo code!
You are most welcome. I am definitely a proponent of avoiding
casts whenever possible.