View Issue Details Jump to Notes ] Print ]
IDProjectCategoryView StatusDate SubmittedLast Update
0013786CMakeCMakepublic2012-12-12 05:012016-06-10 14:31
ReporterAndreas Mohr 
Assigned ToKitware Robot 
PriorityhighSeveritymajorReproducibilityalways
StatusclosedResolutionmoved 
PlatformPCOSLinux / WindowsOS VersionRHEL5 / 7
Product VersionCMake 2.8.10.2 
Target VersionFixed in Version 
Summary0013786: function() set(PARENT_SCOPE) buggy: very surprising warn-uninitialized inconsistency for (non-)empty values
DescriptionI tried to get all my code free of issues,
thus I enabled --warn-uninitialized.
I was very surprised to find that initialization state of a function result (PARENT_SCOPE) variable is being very negatively influenced by the value of the passed variable being empty vs. non-empty,
as can be gathered from the sample below warning about result_empty yet properly *not* warning about result_non_empty.

This should emphatically _not_ be the case - a result variable should *always* get properly initialized (instantiated) in outer scope, no fr****n' matter which value it may happen to get assigned.

And it's not a "this variable already exists in outer scope" vs. "does not exist --> problem" issue: when assigning non-empty values the outer-scope variable *does* get created, yet not for empty ones --> BUG.

Note that pre-initializing the result var to "" prior to invoking the function does successfully silence the initialization warning.
And note that doing this initialization with a non-empty value and subsequently calling the function *does* let the function reset the variable to empty - IOW the variable *does* get assigned by the function in *this* case - just not if it didn't exist previously!

Happening on both Win7 2.8.10.2 and RHEL5 2.8.8.....

Severity major and prio high since it's a foundation-shattering inconsistency ;)

Given this bug it's impossible to get one's code warning-free (when making use of clean result-use-only variable getter functions which happen to return empty values in certain conditions).
A mere "not succeeding in getting the code warning-free" is a rather benign concern - some actively disrupting bug scenarios due to this issue might be conceivable, too.

Thanks!
Steps To Reproducecmake_minimum_required(VERSION 2.8)

function(getter _result)
  set(result_ "${desired_result}")
  set(${_result} "${result_}" PARENT_SCOPE)
endfunction(getter _result)

#set(result_empty "bye, cruel world") # <---- toggle this!

set(desired_result "")
getter(result_empty)

set(desired_result "non-empty")
getter(result_non_empty)

message("result_empty ${result_empty}, result_non_empty ${result_non_empty}.")
Additional Information$ cmake --warn-uninitialized .
Warn about uninitialized values.
CMake Warning (dev) at /home/amoh/privat/cmake_tests/bug_function_result_uninitialized_warning/CMakeLists.txt:14:
  uninitialized variable 'result_empty'
This warning is for project developers. Use -Wno-dev to suppress it.

result_empty , result_non_empty non-empty.
-- Configuring done
-- Generating done
TagsNo tags attached.
Attached Files

 Relationships

  Notes
(0031887)
Andreas Mohr (reporter)
2012-12-14 03:46

Source side analysis:

Source/cmSetCommand.cxx currently has:

  if (parentScope)
    {
    if (value.empty())
      {
      this->Makefile->RaiseScope(variable, 0);
      }
    else
      {
      this->Makefile->RaiseScope(variable, value.c_str());
      }
      return true;
    }


git blame shows that

commit fc8ce174334c3c33141d37ff2b86ea50226b7ce4
Author: Alexander Neundorf <neundorf@kde.org>
Date: Fri Jan 18 15:52:54 2008 -0500

    ENH: remove RAISE_SCOPE() again and instead add SET(<var> <value> PARENT_SCOPE)
    
    Alex

changed it from

- if (args.size() == 1)
- {
- this->Makefile->RaiseScope(args[0].c_str(), 0);
- }
- else
- {
- this->Makefile->RaiseScope(args[0].c_str(), args[1].c_str());
- }


raise_scope() was documented (git show of this commit) to remove the variable in parent scope in case of a *missing* second arg (variable value).
For raise_scope() this API behaviour likely made sense.
For set(PARENT_SCOPE), value.empty() gets transformed to the former "missing second arg" case, thus the variable gets removed, *even if it does have a valid empty string*!


Note that we seem to have a second problem, too:
When pre-setting a variable (the "toggle this!" case in my sample above) *prior* to invalidating it via set(PARENT_SCOPE) in a function sub scope, there will *not* be an "uninitialized variable" warning printed for a subsequent access by parent scope. However, this is what I would expect for the "removed from the parent scope" case of raise_scope(). The variable should not merely be marked "removed" (by setting its value to empty string, NULL, or whatever), but marked "uninitialized" as well, that's what I would have expected (however whether my expectation actually matches desireable best practice behaviour remains to be discussed, i.e. whether a variable with a former "valid" state should be reverted to "uninitialized" state).
(0033765)
Mark Abraham (reporter)
2013-08-30 08:03
edited on: 2013-08-30 08:16

I see similar behaviour with

set(varname value PARENT_SCOPE)

in a CMakeLists.txt accessed via add_subdirectory(), using cmake 2.8.10.1 (distro) and 2.8.11 (compiled by me) on Ubuntu 13.04. Whether or not varname has a previous value in local or parent scope, the call to set() does not set varname to the new value, in either scope.

(0042169)
Kitware Robot (administrator)
2016-06-10 14:28

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.

 Issue History
Date Modified Username Field Change
2012-12-12 05:01 Andreas Mohr New Issue
2012-12-14 03:46 Andreas Mohr Note Added: 0031887
2013-08-30 08:03 Mark Abraham Note Added: 0033765
2013-08-30 08:04 Mark Abraham Note Edited: 0033765
2013-08-30 08:07 Mark Abraham Note Edited: 0033765
2013-08-30 08:16 Mark Abraham Note Edited: 0033765
2016-06-10 14:28 Kitware Robot Note Added: 0042169
2016-06-10 14:28 Kitware Robot Status new => resolved
2016-06-10 14:28 Kitware Robot Resolution open => moved
2016-06-10 14:28 Kitware Robot Assigned To => Kitware Robot
2016-06-10 14:31 Kitware Robot Status resolved => closed


Copyright © 2000 - 2018 MantisBT Team