POV-Ray : Newsgroups : povray.advanced-users : problem using ORs and strcmp() in #switch/#case : Re: problem using ORs and strcmp() in #switch/#case Server Time
29 Apr 2024 12:06:07 EDT (-0400)
  Re: problem using ORs and strcmp() in #switch/#case  
From: clipka
Date: 8 Nov 2017 08:16:08
Message: <5a030398$1@news.povray.org>
Am 08.11.2017 um 04:59 schrieb Kenneth:
> "Bald Eagle" <cre### [at] netscapenet> wrote:
>>
>> I see where it's going wrong, and this will give you an idea of why:
>>
>>     #switch(true)
>>
>>     #case(1)
>>      rgb <0, 0, 0.2>
>>     #break
>>
>>     #case(
>>        // no (strcmp(IMG_TYPE,AA), which is the only 'correct' match
>>        (strcmp(IMG_TYPE,BB))
>>        | (strcmp(IMG_TYPE,CC))
>>      )
>>
>> #switch(true) is a very strange usage, and I'm sure clipka could give some
>> source-code explanation of why it works the way it does.
>> But basically, as I suspected, it just selects the FIRST #case() regardless of
>> what it is.
> 
> But here's a very similar example (though without any ORs, which might make all
> the difference), and it selects the 2nd #case (green)...
> 
> #switch(true)
> #case(0)
>      rgb <0, 0, 0.2> // BLUE
> #break
> #case(1)
>     rgb <0,1,0> // GREEN
> #break
> .....
> 
> This makes sense to me (well, at the moment, anyway!), as it looks like
> #switch(true) is picking the #case with the appropriate 'true' result of (1)
>>
>> In fact, check out:
>>
>>     #switch(strcmp(IMG_TYPE,BB) | strcmp(IMG_TYPE,CC) )
>>
>>      #case(-10)
>>      rgb <1, 1, 0>
>>     #break
>>
>>      #case(-6)
>>      rgb <1, 1, 1>
>>     #break
>>
>>     #case(1)
>>      rgb <0, 0, 0.2>
>>     #break
>>
>>     #case(1000)
>>
>> It selects the blue pigment, which corresponds to 1.
> 
> *That's* a really unexpected result, IMO; neither of the #switch's strcmp()s
> 'match' IMG_TYPE (which would be AA), yet #case(1) is chosen as if #switch is
> 'true.' And looking at it in a different brain-twisting way (one that's
> incorrect, no doubt), it seems that either #case(-6) or #case(-10) should be
> chosen, but certainly not #case(1)
> 
> It all makes my brain hurt :-O

The `#switch` statement expression has no special treatment of logical
operators.

The logical-OR operator `A|B` returns `false` (0) if both A and B are
equivalent to `false` (0); otherwise, it returns or `true` (non-0, in
this case 1).

However, the `strcmp(A,B)` function does /not/ return a boolean value,
but a numerical one: Negative if A<B, positive if A>B, and zero if A=B.
It is therefore highly recommended to always and immediately compare the
`strcmp()` result with zero (unless you know exactly what you're doing),
which turns it into a reasonably easy-to-grasp logical expression.

For example, to examine whether A is "larger" than B, you would write
`strcmp(A,B)>0`.

Then again, with v3.7 you should really use `A>B`.


If you really want to use the `strcmp()` result directly as a boolean
value, you should ditch the idea of it as an equality test, and think of
it as a /non-equality/ test instead: The result will be non-zero (and
thus equivalent to `true`) if the two strings /differ/.


Post a reply to this message

Copyright 2003-2023 Persistence of Vision Raytracer Pty. Ltd.