Anupam
Anupam

Reputation: 49

Issue with Lambda's capture clause

I am trying to use ftw function to calculate size of a directory. The prototype of ftw function is:

int ftw(const char *dirpath,
        int (*fn) (const char *fpath, const struct stat *sb,
                   int typeflag),
        int nopenfd);

To calculate the size of the entire directory, I am trying to use below code using lambda expression:

uint32_t calcDirSize(const char *path) {
   uint32_t usize = 0;

   if (ftw(path, [&usize](const char *fpath, const struct stat *sb, int typeflag) {
                     usize += sb->st_size;
                     return 0;
             }, 1)) {
    return 0;
   }

   return usize;
}

It is throwing error for the variable in the capture clause of the lambda expression. I want to use a local variable to calculate the size and return from calcDirSize function once it is calculated. Is there any other way to achieve the same result?

Upvotes: 0

Views: 132

Answers (1)

super
super

Reputation: 12928

A lambda is only convertable to a function-pointer if it is stateless, or in other words does not capture anything.

You are only allowed to use variables outside of the lambda without a capture if they have static storage duration.

uint32_t calcDirSize(const char *path) {
   static uint32_t usize = 0;
   usize = 0; // Make sure it's reset to 0 every time the function is called.


   if (ftw(path, [](const char *fpath, const struct stat *sb, int typeflag) {
                     usize += sb->st_size;
                     return 0;
             }, 1)) {
    return 0;
   }

   return usize;
}

By making usize static we can remove the capture in the lambda, and that makes it convertable to a function pointer.

Edit: As pointed in the comments this is not thread-safe as multiple calls to calcDirSize could modify/read usize at the same time.

Upvotes: 3

Related Questions