Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to explicitly instantiate temporary variables in C++?

Tags:

c++

Some people are warning that locks can be mis-used by writing:

std::unique_lock<std::mutex>(mutex);

instead of the following correct statement:

std::unique_lock<std::mutex> lock(mutex);

I.e. create an unnamed temporary variable instead of a local variable. The temporary variable would be destroyed immediately and unlock the mutex prematurely.

See for instance gperftools (line 321-324) header:

// Catch bug where variable name is omitted, e.g. MutexLock (&mu);
#define MutexLock(x) COMPILE_ASSERT(0, mutex_lock_decl_missing_var_name)
#define ReaderMutexLock(x) COMPILE_ASSERT(0, rmutex_lock_decl_missing_var_name)
#define WriterMutexLock(x) COMPILE_ASSERT(0, wmutex_lock_decl_missing_var_name)

This macro is written to protect again such use cases.

But can it still happen? Apparently a recent enough GCC or clang will produce errors in this case:

#include <iostream>

class Mutex {};

class Lock {
public:
  explicit Lock(Mutex */* dummy */) { std::cout << __PRETTY_FUNCTION__ << std::endl; }
  ~Lock() { std::cout << __PRETTY_FUNCTION__ << std::endl; }
};

int main() {
  Mutex mutex;
  {
    Lock l(&mutex);
  }
  {
    Lock(&mutex); // This line does not compile.
  }
  return 0;
}

And the error:

g++ foo.cpp
foo.cpp:17:11: error: declaration of reference variable 'mutex' requires an initializer
    Lock(&mutex);
          ^~~~~
1 error generated.

Could someone exhibit a repro case where such a macro would catch a real bug? I could not come up with one so far.

like image 926
Thomas Moulard Avatar asked Nov 17 '15 04:11

Thomas Moulard


People also ask

What is temporary variable in C?

In computer programming, a temporary variable is a variable with short lifetime, usually to hold data that will soon be discarded, or before it can be placed at a more permanent memory location. Because it is short-lived, it is usually declared as a local variable, i.e., a variable with local scope.

How do you declare a temporary variable in C++?

From C++ 17 you can declare temporary variables on if and switch statements just like loops. As the variables are temporary, you can't access those variables as they are only declared in the if or switch block.


1 Answers

You are actually being saved by the disambiguation rule for things-that-can-be-declarations (they are parsed as declarations, not expressions), coupled with the rule requiring references to be initialized.

It won't save you here:

std::mutex m;
int main(){
    std::unique_lock<std::mutex>(m); // m is a local default-constructed unique_lock
}

or here:

struct C { Mutex m; } c;
int main() {
    Lock(&c.m);  // Constructs and destroys a temporary lock.
 }
like image 88
T.C. Avatar answered Sep 28 '22 07:09

T.C.