[CMake] Functions inherit parent variables?

Michael Hertling mhertling at online.de
Fri Mar 2 22:47:45 EST 2012


On 03/03/2012 02:29 AM, Robert Dailey wrote:
> Well you're really comparing apples to oranges. C++ nested scoping rules
> really have nothing to do with two separate functions sharing scoped
> variables. It doesn't even really serve as a good analogy, so I can't be
> 100% certain what you were trying to tell me ;-)

What I actually intended to express is that

(1) C/C++'s static block scoping has the same effect as CMake's dynamic
    function scoping *insofar* that the inner scope has access to the
    outer scope - as usual - and

(2) in C/C++, a function can't see a calling function's variables for
    the reason alone that they don't have nested scopes, but the fact
    that caller and callee don't have nested static scopes in C/C++
    doesn't mean that they don't have nested dynamic ones in CMake.

Probably, as I said before, a quite silly idea...

> However I appreciate your response. I really just wanted to make sure this
> isn't a bug, because the way the called function inherits the calling
> function's local variables is an unusual behavior for a language, at least
> in my experience. So I had to think twice about it ;)

AFAIK, it's unusual for languages knowing nested functions, but
CMake doesn't know them. Among the nested-knowing ones, e.g.,
Python can do

def outer():
    value = 123
    print "outer:",value
    def inner(): print "inner:",value
    inner()
    value = 321
outer()
outer()

whereas Perl 5 can do it only once ("will not stay shared")

use warnings;
use strict;
sub outer {
    my $value;
    $value = 123;
    print "outer: $value\n";
    sub inner { print "inner: $value\n"; }
    inner();
    $value = 321;
}
outer();
outer();

but Perl 6, in turn, is said to do it like Python.

We're getting off-topic, I guess.

Regards,

Michael

> On Fri, Mar 2, 2012 at 6:53 PM, Michael Hertling <mhertling at online.de>wrote:
> 
>> On 03/01/2012 06:01 PM, Robert Dailey wrote:
>>> No, the print statement is not missing. In fact it prints just fine
>>> (function test() is able to obtain the value for variable SOME_TEST).
>>
>> I meant the output "SOME_TEST: HELLO WORLD" was missing in your report.
>>
>>> This isn't exactly the same as C++. In C++, a function does not have
>> access
>>> to the calling function's local declarations. In order for the function
>> to
>>> get access to these, they must be passed in as parameters.
>>
>> There wasn't talk of functions but of the "{" and "}" tokens:
>>
>> #include <stdio.h>
>>
>> int main(void)
>> {
>>    int outer = 1;
>>    {
>>        int inner = 2;
>>        printf("outer=%d, inner=%d\n",outer,inner);
>>    }
>>    return 0;
>> }
>>
>> As you will see, there's access to the outer scope from the inner one.
>>
>> However, to be more precise, C/C++'s scoping is static, i.e. it's in
>> effect at compilation time only, and - in contrast to Pascal, e.g. -
>> the ISO dialects don't allow a nested definition of functions, so a
>> function's scope isn't part of another function's one. Therefore, a
>> called function can't see the variables of the calling function as
>> their scopes aren't descendants but siblings.
>>
>> Interpreted languages like CMake's one often have dynamic scoping,
>> i.e. an invocation of a function creates a new scope - capable to
>> hold variables - and pushes it on a stack from where it is popped
>> and destroyed when the function terminates. When dereferencing a
>> variable, it is searched by traversing the stacked scopes from
>> inner to outer until it is found. Therefore, a called function
>> can see the calling function's variables since the latter's
>> scope is accessible from the former's one.
>>
>> Maybe, it was a rather bad idea to compare C/C++'s static
>> block scoping with CMake's dynamic function scoping.
>> Sorry about that.
>>
>> Regards,
>>
>> Michael
>>
>>> On Wed, Feb 29, 2012 at 9:54 PM, Michael Hertling <mhertling at online.de
>>> wrote:
>>>
>>>> On 03/01/2012 01:38 AM, Robert Dailey wrote:
>>>>> I ran a quick test:
>>>>>
>>>>>
>>>>> function( test )
>>>>> message( "SOME_TEST: ${SOME_TEST}" )
>>>>> endfunction()
>>>>>
>>>>> function( start )
>>>>> set( SOME_TEST "HELLO WORLD" )
>>>>> test()
>>>>> endfunction()
>>>>>
>>>>> start()
>>>>>
>>>>>
>>>>> Seems like a function has access to the calling scope's defined
>>>> variables.
>>>>> I thought because functions created a new scope, that excluded access
>> to
>>>>> variables defined in the outer scope (i.e. calling scope)
>>>>>
>>>>> Can someone explain?
>>>>
>>>> The line "SOME_TEST: HELLO WORLD" is missing, I guess?
>>>>
>>>> As usual with scoping mechanisms, there is access to the outer scope
>>>> from within the inner scope: Read access via ordinary dereferencing
>>>> and write access via PARENT_SCOPE. It's quite the same as in C/C++
>>>> with the { and } tokens; see also the C++ "::" operator.
>>>>
>>>> Regards,
>>>>
>>>> Michael


More information about the CMake mailing list