Why are nested functions not supported by the C st

2019-01-14 17:14发布

It doesn't seem like it would be too hard to implement in assembly.

gcc also has a flag (-fnested-functions) to enable their use.

10条回答
Fickle 薄情
2楼-- · 2019-01-14 17:55

I'd like to quote something from the BDFL (Guido van Rossum):

This is because nested function definitions don't have access to the local variables of the surrounding block -- only to the globals of the containing module. This is done so that lookup of globals doesn't have to walk a chain of dictionaries -- as in C, there are just two nested scopes: locals and globals (and beyond this, built-ins). Therefore, nested functions have only a limited use. This was a deliberate decision, based upon experience with languages allowing arbitraries nesting such as Pascal and both Algols -- code with too many nested scopes is about as readable as code with too many GOTOs.

Emphasis is mine.

I believe he was referring to nested scope in Python (and as David points out in the comments, this was from 1993, and Python does support fully nested functions now) -- but I think the statement still applies.

The other part of it could have been closures.

If you have a function like this C-like code:

(*int()) foo() {
    int x = 5;
    int bar() {
        x = x + 1;
        return x;
    }
    return &bar;
}

If you use bar in a callback of some sort, what happens with x? This is well-defined in many newer, higher-level languages, but AFAIK there's no well-defined way to track that x in C -- does bar return 6 every time, or do successive calls to bar return incrementing values? That could have potentially added a whole new layer of complication to C's relatively simple definition.

查看更多
Deceive 欺骗
3楼-- · 2019-01-14 17:56

It also wouldn't be too hard to add members functions to structs but they are not in the standard either.

Features are not added to C standard based on soley whether or not they are easy to implement. It's a combination of many other factors including the point in time in which the standard was written and what was common / practical then.

查看更多
Summer. ? 凉城
4楼-- · 2019-01-14 17:59

I disagree with Dave Vandervies.

Defining a nested function is much better coding style than defining it in global scope, making it static and adding a comment saying "This is a helper function used only by myfunc()".

What if you needed a helper function for this helper function? Would you add a comment "This is a helper function for the first helper function used only by myfunc"? Where do you take the names from needed for all those functions without polluting the namespace completely?

How confusing can code be written?

But of course, there is the problem with how to deal with closuring, i.e. returning a pointer to a function that has access to variables defined in the function from which it is returned.

查看更多
一纸荒年 Trace。
5楼-- · 2019-01-14 17:59

Either you don't allow references to local variables of the containing function in the contained one, and the nesting is just a scoping feature without much use, or you do. If you do, it is not a so simple feature: you have to be able to call a nested function from another one while accessing the correct data, and you also have to take into account recursive calls. That's not impossible -- techniques are well known for that and where well mastered when C was designed (Algol 60 had already the feature). But it complicates the run-time organization and the compiler and prevent a simple mapping to assembly language (a function pointer must carry on information about that; well there are alternatives such as the one gcc use). It was out of scope for the system implementation language C was designed to be.

查看更多
登录 后发表回答