MantisBT - CMake
View Issue Details
0015709CMakeCMakepublic2015-08-24 08:392016-06-10 14:31
Jan Christoph Uhde 
Kitware Robot 
normalminoralways
closedmoved 
 
 
0015709: variables defined state is not reset after using it for iteration in foreach
When using a prior undefined variable in a foreach(x ${foo}) loop it is still defined after the loop.

We noticed it due to the following warning:

/usr/share/cmake-3.2/Modules/CheckSymbolExists.cmake:

53 macro(_CHECK_SYMBOL_EXISTS SOURCEFILE SYMBOL FILES VARIABLE)
54 if(NOT DEFINED "${VARIABLE}" OR "x${${VARIABLE}}" STREQUAL "x${VARIABLE}")

-- Looking for include file pthread.h - found
CMake Warning (dev) at /usr/share/cmake-3.2/Modules/CheckSymbolExists.cmake:54 (if):
  Policy CMP0054 is not set: Only interpret if() arguments as variables or
  keywords when unquoted. Run "cmake --help-policy CMP0054" for policy
  details. Use the cmake_policy command to set the policy and suppress this
  warning.

  Quoted variables like "x" will no longer be dereferenced when the policy is
  set to NEW. Since the policy is not set the OLD behavior will be used.
Call Stack (most recent call first):
  /usr/share/cmake-3.2/Modules/CheckSymbolExists.cmake:50 (_CHECK_SYMBOL_EXISTS)
  /usr/share/cmake-3.2/Modules/FindThreads.cmake:133 (CHECK_SYMBOL_EXISTS)
  5axis/test/exactoutputBTOneFile/CMakeLists.txt:13 (find_package)
This warning is for project developers. Use -Wno-dev to suppress it.

The name "x" was not a good choice. But the behavior is really unintuitive.


Cheers

Jan
cmake_minimum_required(VERSION 3.2)

set(FOO "this" "is" "borken")

foreach(x ${FOO})
    message(mesage: ${x})
endforeach()

if(DEFINED x)
    message("x is still defined")
endif()
No tags attached.
Issue History
2015-08-24 08:39Jan Christoph UhdeNew Issue
2015-08-24 09:03kislinskNote Added: 0039317
2015-08-24 09:15Nils GladitzNote Added: 0039318
2015-08-24 10:01Brad KingNote Added: 0039321
2015-08-24 11:14Ben BoeckelNote Added: 0039324
2016-06-10 14:29Kitware RobotNote Added: 0042826
2016-06-10 14:29Kitware RobotStatusnew => resolved
2016-06-10 14:29Kitware RobotResolutionopen => moved
2016-06-10 14:29Kitware RobotAssigned To => Kitware Robot
2016-06-10 14:31Kitware RobotStatusresolved => closed

Notes
(0039317)
kislinsk   
2015-08-24 09:03   
Isn't this actually expected behavior as CMake has dynamic scope for functions and directories only (see http://www.cmake.org/cmake/help/v3.3/manual/cmake-language.7.html#variables [^])?
(0039318)
Nils Gladitz   
2015-08-24 09:15   
The value of the loop variable is restored after the loop which means that scoping is somewhat implemented ... it just currently is limited to its value and does not apply to its DEFINED state.

The documentation does not state what the scope of the loop variable is but I don't think this is expected behaviour either.
(0039321)
Brad King   
2015-08-24 10:01   
The save/restore logic is here:

 http://www.cmake.org/gitweb?p=cmake.git;a=blob;f=Source/cmForEachCommand.cxx;hb=v3.3.1#l46 [^]
 http://www.cmake.org/gitweb?p=cmake.git;a=blob;f=Source/cmForEachCommand.cxx;hb=v3.3.1#l90 [^]

Indeed it does not remove the definition completely if it was not defined before, and instead just sets it to the empty string.
(0039324)
Ben Boeckel   
2015-08-24 11:14   
Hmm, I thought CMake was function-scoped. Learn something new every day :) . In any case, this will likely need a policy.
(0042826)
Kitware Robot   
2016-06-10 14:29   
Resolving issue as `moved`.

This issue tracker is no longer used. Further discussion of this issue may take place in the current CMake Issues page linked in the banner at the top of this page.