16

This seems to work on the platforms I have tried:

#include <iostream>

// extern "C" linkage
extern "C" void foo(void (*fn_ptr)(int));

namespace {
  struct bar {
    static void f(int);
  };
}

int main() {
  // Usually works on most platforms, not guaranteed though:
  foo(bar::f);

  // Probably equally bad or worse?
  foo([](int x) { std::cout << x << std::endl; });
}

but then again passing a static member function also worked on these platforms when it was not required to.

Is there a way to force a lambda to have suitable linkage to make this safe and portable? Or is it already?

Community
  • 1
  • 1
Flexo
  • 87,323
  • 22
  • 191
  • 272
  • What you have there __is__ safe already. – ildjarn Sep 04 '11 at 19:24
  • 4
    @ildjarn - § 7.5.1 - "Two function types with different language linkages are distinct types even if they are otherwise identical." – Flexo Sep 04 '11 at 19:29
  • 1
    possible duplicate of [Will C++0x support __stdcall or extern "C" capture-nothing lambdas?](http://stackoverflow.com/questions/2935201/will-c0x-support-stdcall-or-extern-c-capture-nothing-lambdas) – Flexo Sep 24 '11 at 14:58
  • yup, that dupe gets my vote too – underscore_d Mar 12 '17 at 17:18

1 Answers1

9

No. Lambdas are ultimately objects that have a function call operator. A captureless lambda can be converted into a function pointer of its appropriate type, but that function pointer will be a C++ function with C++ linkage.

Nicol Bolas
  • 449,505
  • 63
  • 781
  • 982
  • 1
    SO ... why can't it be passed as an argument to a C function? :( –  Sep 04 '11 at 19:19
  • 1
    Agreed, that looks like it's the official position given "The closure type for a lambda-expression with no lambda-capture has a public non-virtual non-explicit const conversion function to pointer to function having the same parameter and return types as the closure type’s function call operator. The value returned by this conversion function shall be the address of a function" makes no mention of linkage it's safe to assume it is C++ linkage and therefore a distinct type. – Flexo Sep 04 '11 at 19:57
  • 1
    user166390: because it is not defined as having C linkage, which C functions necessarily require. – underscore_d Mar 12 '17 at 17:15