0

I looked at this excellent answer but can't figure out how to apply it to this snipped:

//this is in the .hpp file
std::atomic<int> size = 10;
std::recursive_mutex *locks[2];

//in some function of the class
//it's important that the 2nd array dimension is dynamic
the_lock[0] = new std::recursive_mutex[size]; 
the_lock[1] = new std::recursive_mutex[size];
std::recursive_mutex (*locks_2)[2][size] = &locks;

The assignment gives me

error: cannot convert ‘std::recursive_mutex* (*)[2]’ to ‘std::recursive_mutex (*)
[2][(((sizetype)(((ssizetype)((**here be long type information, since I'm using
templates a lot**, long unsigned int, std::less<long unsigned int>          
>::size.std::atomic<long unsigned 
int>::<anonymous>.std::__atomic_base<_IntTp>::operator 
std::__atomic_base<_IntTp>::__int_type<long unsigned int>()) + -1)) + 1)]’ in 
initialization

How can I obtain a pointer to 'locks'?

Community
  • 1
  • 1
mort
  • 12,988
  • 14
  • 52
  • 97
  • 1
    Arrrr... please don't call your mutex "lock". A mutex is a mutex, and a lock is a lock. – Kerrek SB Jul 03 '13 at 22:10
  • Sorry for that. I'm trying to implement Java-style pseudo code from a book and am keeping the names to avoid confusion – mort Jul 03 '13 at 22:13
  • OK -- I think that's saying more about Java than about you :-) (Or at least about the book.) – Kerrek SB Jul 03 '13 at 22:13
  • Any reason to allocate each object individually? – n0rd Jul 03 '13 at 22:17
  • Why should a Java based book call it's locks "mutex"? – mort Jul 03 '13 at 22:18
  • @mort: In concurrency, a "lock" typically means "holding a lock", which is a *state*. By contrast the mutex is the underlying data which stores the state. You have one mutex per shared resource, but you have one lock in each thread. Being clear about this in your mind can make all the difference in understanding concurrent code. – Kerrek SB Jul 03 '13 at 22:21
  • @KerrekSB: True, but Java does not expose the user with mutexes. Do you seriously suggest to write 'Lock mutex;' in Java? – mort Jul 03 '13 at 22:26
  • I don't know Java, but I'm getting the impression that it's doing something different from what you're trying to do in C++, so perhaps this isn't a fair comparison. I just know when the C++ looks off :-S – Kerrek SB Jul 03 '13 at 22:29

3 Answers3

3

The error message is actually giving away the solution for free:

std::recursive_mutex * (*locks_2)[2] = &locks;
Kerrek SB
  • 464,522
  • 92
  • 875
  • 1,084
  • This does NOT WORK! ' error: cannot convert ‘std::recursive_mutex* (*)[2]’ to ‘std::recursive_mutex (*)[2]’ in initialization' – mort Jul 03 '13 at 22:15
  • @mort: Sorry, my bad, forgot a `*`. Fixed. – Kerrek SB Jul 03 '13 at 22:18
  • I accepted this answer because it helped figure out the correct type. However, the other answers are correct as well. – mort Jul 03 '13 at 22:33
2

One can use the fact that this sort of thing has been officially declared to be ridiculously hard to get right for no apparent reason that the compiler cannot solve for you. If your compiler supports C++ 2011 that is. Use:

auto my_ptr = &locks; // point to locks, let the compiler worry about types

Requires that you compile your code as C++ 2011 though. (-std=c++11 for GCC).

user268396
  • 11,576
  • 2
  • 31
  • 26
1

locks is just an array of pointers. So you could use a pointer pointer to point to it.

std::recursive_mutex **locks_2 = locks;
paul
  • 1,212
  • 11
  • 15