Don't make set remove a variable
It occured during the discussion of !2748 (merged) that it is rather surprising that set(var)
unsets a variable.
Consider:
function(foo res)
set(bar "")
set(${res} ${bar} PARENT_SCOPE)
endfunction()
set(myVar "default")
foo(myVar)
if(myVar) # OR if(myVar STREQUAL "") OR if(myVar STREQUAL "something")
do something
endif()
This code looks fine as the result variable is set and checked with the "easy" and short way as if
specifically allows using a variable.
However this contains a subtle bug as the set
in foo
removes the variable from the scope. This might even mean, a cache variable now comes into scope. Both scenarios are most likely not intended and lead to a lot of confusion or disaster.
I therefore propose to create a new policy under which set(var)
is equivalent to set(var "")
and hence set
does never work as unset
.
I do not think this will break much existing code as if(myVar)
will now work where it didn't before so was most likely not used and only case where this is noticeable would be if(NOT DEFINED myVar)
which I doubt many use over e.g. if("${myVar}" STREQUAL "")
in this cases.
Note: The docs do mention this but only in an added sentence which I missed several times until I specifically searched for it:
Zero arguments will cause normal variables to be unset. See the unset() command to unset variables explicitly.
This implies that for set(...CACHE...)
it will set an empty cache variable(?) which again is unexpected. Again the proposed behaviour is more clear and predictable.
At the very least the docs should make a strongly visible hint out of that sentence.