Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can this C code have lambda

Tags:

c

lambda

This code:

#include <stdio.h>

int main()
{
    void (^a)(void) = ^ void () { printf("test"); } ;
    a();
}

Compile without warning with clang -Weverything -pedantic -std=c89 (version clang-800.0.42.1) and print test.

I could not find any information about standard C having lambda, also gcc has it's own syntax for lambda and it would be strange for them do this if a standard solution existed.

like image 312
mantal Avatar asked Jan 17 '17 15:01

mantal


2 Answers

This behavior seems to be specfic to newer versions of Clang, and is a language extension called "blocks".

The Wikipedia article on C "blocks" also provides information which supports this claim:

Blocks are a non-standard extension added by Apple Inc. to Clang's implementations of the C, C++, and Objective-C programming languages that uses a lambda expression-like syntax to create closures within these languages. Blocks are supported for programs developed for Mac OS X 10.6+ and iOS 4.0+, although third-party runtimes allow use on Mac OS X 10.5 and iOS 2.2+ and non-Apple systems.

Emphasis above is mine. On Clang's language extension page, under the "Block type" section, it gives a brief overview of what the Block type is:

Like function types, the Block type is a pair consisting of a result value type and a list of parameter types very similar to a function type. Blocks are intended to be used much like functions with the key distinction being that in addition to executable code they also contain various variable bindings to automatic (stack) or managed (heap) memory.

GCC also has something similar to blocks called lexically scoped nested functions. However, there are some key differences also note in the Wikipedia articles on C blocks:

Blocks bear a superficial resemblance to GCC's extension of C to support lexically scoped nested functions. However, GCC's nested functions, unlike blocks, must not be called after the containing scope has exited, as that would result in undefined behavior.

GCC-style nested functions also require dynamic creation of executable thunks when taking the address of the nested function. [...].

Emphasis above is mine.

like image 85
Christian Dean Avatar answered Sep 27 '22 20:09

Christian Dean


the C standard does not define lambdas at all but the implementations can add extensions.

Gcc also added an extension in order for the programming languages that support lambdas with static scope to be able to convert them easily toward C and compile closures directly.

Here is an example of extension of gcc that implements closures.

#include <stdio.h>

int(*mk_counter(int x))(void)
{
    int inside(void) {
        return ++x;
    }
    return inside;
}

int
main() {
    int (*counter)(void)=mk_counter(1);
    int x;
    x=counter();
    x=counter();
    x=counter();
    printf("%d\n", x);
    return 0;
}
like image 42
alinsoar Avatar answered Sep 27 '22 20:09

alinsoar