Tiib <
oot...@hot.ee> writes:
> On Tuesday, 15 September 2020 08:04:52 UTC+3, Bonita Montero wrote:
>
>>> Neither for() nor if() nor switch() now while() nor ?: is needed
>>> for Turing completeness:
>>> static int
>>> give_a( int a, int b ){
>>> return a;
>>> }
>>>
>>> static int
>>> give_b( int a, int b ){
>>> return b;
>>> }
>>>
>>> int
>>> no_control_max( int a, int b ){
>>> int (*choose[2])( int, int ) = { give_a, give_b };
>>> return choose[ b > a ]( a, b );
>>> }
>>> Compiles cleanly as both C{90,99,11} and C++{98,03,11,14,17}.
>>
>> It needs a good compiler to optimize away these stupid
>> function-calls. Otherwise this code would be rather slow.
>
> Yes, but it usually is not generating branches like I did ask.
Do you mind if I ask what is motivating the original question?
Or what the criteria are for a successful answer? The answer
I gave was somewhat tongue-in-cheek since even though it was
not using if() or ?: I was pretty sure it was not what you
were looking for.
I do have a solution that uses only common operators, and no
function call trickery (and of course no library functions), and
thus likely satisfies what you would call "raw" C++, but before I
post something more I want to be sure I know what it is you're
really looking for.
> Your trick, Bonita, is also good as majority of compilers
> (and all popular) optimize that ?: away on targets.
> For example on RISC-V:
>
> bonita_max(int, int):
> slt a5,a0,a1
> subw a5,zero,a5
> xor a1,a0,a1
> and a1,a1,a5
> xor a0,a0,a1
> sext.w a0,a0
> ret
>
> tim_max(int, int):
> sgt a5,a1,a0
> slli a4,a5,3
> lui a5,%hi(.LANCHOR0)
> addi a5,a5,%lo(.LANCHOR0)
> add a5,a5,a4
> ld t1,0(a5)
> jr t1
>
> Interesting trick, jumping to address of called function and letting
> it to return for you.
As tail calls go it's one of the simplest, which makes it one
of the easiest optimizations to do. I'm surprised in a way
that compilers don't do this particular optimization even
at level -O0.