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
27 Apr 2024 02:37:23 EDT (-0400)
  Re: problem using ORs and strcmp() in #switch/#case  
From: clipka
Date: 7 Nov 2017 20:44:53
Message: <5a026195$1@news.povray.org>
Am 07.11.2017 um 20:32 schrieb Kenneth:

>     #switch(1000)
>     #case(
>     // INDIVIDUALLY, these all work the way they are supposed to-- but not
>     // all three at once. The OR's are causing some kind of problem, and
>     // the result always fall through to the #else clause.
>         (strcmp(IMG_TYPE,AA) + 1000)
>         | (strcmp(IMG_TYPE,BB) + 1000)
>         | (strcmp(IMG_TYPE,CC) + 1000)
>          )

Ah... yes... no, don't do that.

The `#switch`/`#case` construct is designed to be used as follows:

    // (A)
    #switch(VARIABLE)
      #case(CONST1)
        // go here if VARIABLE = CONST1
      #break
      #case(CONST2)
        // go here if VARIABLE = CONST2
      #break
      ...
    #end

It so happens that the `#case` values /can/ be other variables (and of
course the `#switch` value /can/ be a constant), allowing for a hack to
co-opt the statement as a replacement for pathologic `#if... #else #if
... #end #end` nesting:

    // (B)
    #switch(true)
      #case(CONDITION1)
        // go here if CONDITION1 is true
      #break
      #case(CONDITION2)
        // otherwise go here if CONDITION2 is true
      #break
      ...
    #end

If the conditions are string equality tests (`strcmp(...)=0`), the
following similar construct is also possible:

    // (C)
    #switch(0)
      #case(strcmp(STRING,CONST1))
        // go here if STRING = CONST1
      #break
      #case(strcmp(STRING,CONST2))
        // otherwise go here if STRING = CONST2
      #break
      ...
    #end

Note however that (B) and (C) *do not mix* nicely -- you have to decide
whether you want your `#case` expressions to be logical tests (allowing
for logical OR, AND etc.) or `strcmp()` results. You can't just try to
mix them (unless you know exactly what you're doing).

Also, there's a much easier way to achieve a logical OR in any `#switch`
construct: Just place multiple `#case` statements without a `#break` in
between, like so:

    #switch(0)
      #case(strcmp(STRING,CONST1A))
      #case(strcmp(STRING,CONST1B))
        // go here if STRING = CONST1A or CONST1B
      #break
      #case(strcmp(STRING,CONST2A))
      #case(strcmp(STRING,CONST2B))
        // otherwise go here if STRING = CONST2A or CONST2B
      #break


Finally, note that as of v3.7, (B) and (C) can be rewritten as:

    // (B)
    #if(CONDITION1)
      // go here if CONDITION1 is true
    #elseif(CONDITION2)
      // otherwise go here if CONDITION2 is true
    ...
    #end

    // (C)
    #if(STRING = CONST1)
      // go here if STRING = CONST1
    #elseif(STRING = CONST2)
      // otherwise go here if STRING = CONST2
    ...
    #end


> Perhaps I shouldn't be using strcmp() at all. It *is* a rather complex beast--

Indeed (though with the `+1000` term you're overcomplicating things).

As of v3.7, the various comparison operators (`=`, `<` etc.) are a much
better choice in most cases, now that they also support strings.


Post a reply to this message

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