Boost condition_variable argument error - boost

I encounter an error in the code below.
recursive_mutex m_RecurMutex;
condition_variable cond;
unique_lock<recursive_mutex> lock(m_RecurMutex);
cond.wait(lock); // Error Here.
What is the reason causing this error?

You should use condition_variable_any instead, the semantics of this version is the same, but it allows all kinds of lock types. The regular condition_variable is however said to be potentially faster.

I assume the error is
mutex.cc: In function ‘int main()’:
mutex.cc:9: error: no matching function for call to ‘boost::condition_variable::wait(boost::unique_lock<boost::recursive_mutex>&)’
/opt/local/include/boost/thread/pthread/condition_variable.hpp:17: note: candidates are: void boost::condition_variable::wait(boost::unique_lock<boost::mutex>&)
i
if not, please correct me. The documentation shows boost::condition_variable::lock takes a boost::unique_lock<boost::mutex> as an argument, not a boost::unique_lock<boost::recursive_mutex> as in your example.

Related

Why Microsoft Error Message uses the word "Token"?

I purposely set a bad path for a CreateDirectory call so that my exception handling code would execute:
I am not sure if this is off topic, but you might have more experience with this. Why is the error text:
An attempt was made to reference a token that does not exist.
Why are they using the word token instead of file or folder?
I will close the question if off topic.
The return value of GetLastError is: 123
According to here:
ERROR_INVALID_NAME
123 (0x7B)
The filename, directory name, or volume label syntax is incorrect.
Now that message makes sense. So why is my Windows 10 showing the other message?
There is no issue with the call to FormatMessage. It works as advertised. However, you aren't passing in the value 123 (ERROR_INVALID_NAME). You are passing 1008 (ERROR_NO_TOKEN), by accident, due to calling GetLastError at the wrong time. GetLastError has a strong requirement:
You should call the GetLastError function immediately when a function's return value indicates that such a call will return useful data. That is because some functions call SetLastError with a zero when they succeed, wiping out the error code set by the most recently failed function.
It's fairly straightforward to satisfy this in C. With C++, things get more complicated, with all the invisible code the compiler generates. The code in question apparently captures the calling thread's last error code only after it enters the CWin32FileError c'tor. That's too late.
Based on the assumption that GetWorkingPath() returns a CString instance by value, and CWin32FileError takes its arguments as CString const&, this is what happens behind the scenes:
if (!CreateDirectory(GetWorkingPath() + _T("whatever"), nullptr))
GetWorkingPath() constructs a temporary CString instance.
operator+(CString const&, LPCTSTR) constructs yet another temporary CString instance, concatenating both inputs.
operator LPCTSTR() is implicitly invoked on the temporary constructed in step 2.
CreateDirectory is called and returns.
Important: The destructor of the temporary created in step 2 is called.
Important: The destructor of the temporary created in step 1 is called.
Steps 5 and 6 are fatal already, potentially changing the calling thread's last error code. And yet, there's even more code getting in the way:
CWin32FileError e(_T("whatever"),
GetWorkingPath() + _T("whatever"));
Important: _T("whatever") triggers CString's conversion constructor (CString(LPCTSTR)), producing a temporary.
Important: GetWorkingPath() constructs a temporary, invoking CString's copy-c'tor.
Important: operator+(CString const&, LPCTSTR) constructs yet another temporary.
The CWin32FileError c'tor finally runs, presumably calling GetLastError.
This adds another 3 candidates (at least) that can modify the calling thread's last error code. To solve this, you're going to have to make sure, that absolutely no code runs in between a failed Windows API call and the call to GetLastError.
To do this, you're going to have to get rid of the temporaries, and move capturing of the last error code outside the CWin32FileError c'tor. A simple solution to the former would be to construct the path name up front, e.g.
auto path_name{ GetWorkingPath() + _T("whatever") };
auto path_name_strptr{ path_name.GetString() };
if (!CreateDirectory(path_name_strptr, nullptr))
// ...
(or use an init-statement in the if statement to limit the scope, if you are using C++17). Either way, your very next call must be GetLastError to capture the last error code while it is still meaningful. However you pass that value into CWin32FileError's c'tor, or which argument types it uses, is up to you. But you cannot rely on that c'tor to capture the last error code for you.

Expression result unused: strange behaviour of c++ compiler?

I accidentally typed the following code but my code successfully built and even ran properly.
std::string myString = "This is my string ";
std::shared_ptr<std::string> s = std::make_shared<std::string>(myString);
p->pushString(s);”accidental typo”;
It just showed a warning Expression result unused.
Why it is not a compiler or run time error?
I am using Xcode editor
Thanks
Why it is not a compiler [...] error?
Because it does not violate any rule of the C++ standard. If a program conforms to the standard then the compiler should allow its compilation. However, it was friendly enough to warn you that the expression is useless.
or run time error?
The expression doesn't result in any executed code, so it would be quite surprising if it resulted in a run time error.
You know that you can have arbitrary expressions as statements? That's how simple functions calls works, or assignments. In fact the statement
p->pushString(s);
is actually such an expression-statement. The p->pushString(s) part is an expression, it's the context (with the terminating semi-colon) that turns it into a statement.
That also means you can do something like
5;
Or in your case
"some string here";
Those are valid statements. They do however produce a result, which is (legally) discarded or ignored, but might cause the compiler to emit a warning about the ignored result.
It's really no different than e.g.
some_function_which_returns_a_result(); // Result ignored

What does :<> mean in a function declaration?

The declaration of funset_nil in the file libats/ML/SATS/funset.sats reads:
fun{} funset_nil{a:t0p} ():<> set(a)
What does :<> mean?
This indicates that the function is pure. No effects shall occur. Please see https://github.com/githwxi/ATS-Postiats/wiki/effects.

Type Mismatch error on WAIT?

This one is making me a little crazy and I hope someone can help.
I added a wait(45) line to my QTP script and when it runs I get a type mismatch error.
I know this will occur if a function can't be called or I misspell something to be called or etc.
But, this is a simple WAIT statement. Nothing else on the line.
Line: 152
Char: 6
Error: Type mismatch: 'Wait'
Code 800A000D
Any ideas? Did I miss something? How can there be a type mismatch on Wait?
There definitely is no Wait() sub or function in VBScript; as this question indicates, this holds for QTP too.
As to the error: a missing sub/function throws a type mismatch:
>> nosuchsub
>>
Error Number: 13
Error Description: Type mismatch
(If this consoles you, I don't like it neither.)
Actual error is not in Wait function. QTP shows type mismatch error due to compilation error in previous lines. Check all your library files are properly added. Best method to find the root cause of problems like this is to divide your code into smaller functions / procedures and test each function.

How can I get more information from clang substitution-failure errors?

I have the following std::begin wrappers around Eigen3 matrices:
namespace std {
template<class T, int nd> auto begin(Eigen::Matrix<T,nd,1>& v)
-> decltype(v.data()) { return v.data(); }
}
Substitution fails, and I get a compiler error (error: no matching function for call to 'begin'). For this overload, clang outputs the following:
.../file:line:char note: candidate template ignored:
substitution failure [with T = double, nd = 4]
template<class T, int nd> auto begin(Eigen::Matrix<T,nd,1>& v)
^
I want this overload to be selected. I am expecting the types to be double and int, i.e. they are deduced as I want them to be deduced (and hopefully correctly). By looking at the function, I don't see anything that can actually fail.
Every now and then I get similar errors. Here, clang tells me: substitution failure, I'm not putting this function into the overload resolution set. However, this does not help me debugging at all. Why did substitution failed? What exactly couldn't be substituted where? The only thing obvious to me is that the compiler knows, but it is deliberately not telling me :(
Is it possible to force clang to tell me what did exactly fail here?
This function is trivial and I'm having problems. In more complex functions, I guess things can only get worse. How do you go about debugging these kind of errors?
You can debug substitution failures by doing the substitution yourself into a cut'n'paste of the original template and seeing what errors the compiler spews for the fully specialized code. In this case:
namespace std {
auto begin(Eigen::Matrix<double,4,1>& v)
-> decltype(v.data()) {
typedef double T; // Not necessary in this example,
const int nd = 4; // but define the parameters in general.
return v.data();
}
}
Well this has been reported as a bug in clang. Unfortunately, the clang devs still don't know the best way to fix it. Until then, you can use gcc which will report the backtrace, or you can apply this patch to clang 3.4. The patch is a quick hack that will turn substitution failures into errors.

Resources