[cmake-developers] Surprising CMP0054 behavior

Craig Scott craig.scott at crascit.com
Mon Mar 26 16:22:57 EDT 2018


On Mon, Mar 26, 2018 at 11:51 PM, Brad King <brad.king at kitware.com> wrote:

> On 03/26/2018 08:07 AM, Craig Scott wrote:
> > Am I missing something, or is the following result surprising to others
> as well:
> >
> > set(somevar YES)
> > if ("somevar")
> >     message("Get here if CMP0054 is OLD (seems okay)")
> > else()
> >     message("Get here if CMP0054 is NEW (surprising?)")
> > endif()
> >
> > I would have thought that even with CMP0054 being NEW, the if condition
> would
> > still evaluate to true since it is going to test a non-empty string that
> > doesn't match any of the defined false constants.
>
> The observed behavior is consistent with the documentation.
>
> `if(<constant>)` enumerates a set of true/false constants and says
> that if it is not one of these then it uses `if(<variable|string>)`.
> That is true only if it is a variable that is defined to a value that
> is not a false constant.  With CMP0054 NEW behavior, `if("string")`
> is always treated as the *string* variant which is never a variable
> defined to anything.
>

Okay, but the net effect of that logic is that for the expression
`if("${someVar}")`, if the value of `someVar` is neither a true nor false
constant, it ends up evaluating to false. This seems the opposite of what
it should be. Most languages generally take the path of if an expression
doesn't evaluate to known false values, the result is true (a la C's
"anything but 0 is considered true" approach). Even CMake's logic here
tries to be like that - it's how the unary if() behaves when given a
variable name rather than a quoted string (if the variable's value is not a
false constant, the result is true). The fact that it's the opposite when
given a string is the surprising part.

Probably the only practical path forward here is to clarify the docs, but
I'm still trying to wrap my head around how it could be explained without
ending up making it look like a confusing mess. At the very least though, I
think the docs for the CMP0054 policy needs an example specifically for
this unary if() scenario. It's just that the explanation that should go
with it is hard.

-- 
Craig Scott
Melbourne, Australia
https://crascit.com
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://cmake.org/pipermail/cmake-developers/attachments/20180327/4ef79947/attachment.html>


More information about the cmake-developers mailing list