condition.wait_for intellisense error - c++

I'm doing a simple tutorial based around threads. In this exercise I am supposed to get threads to wait for each other.
I have copied the example code verbatim with the exception that I'm not using namespace std; and am instead writing in std::each time I need it.
The error in question corresponds to the line:
if (condition.wait_for(std::unique_lock<std::mutex>(mut), std::chrono::seconds(3)))
Intellisense tells me that "the expression must have bool type (or be convertible to bool)" but I looked up the documentation on condition.wait_for and it can return std::cv_status::timeout, std::cv_status::no_timeout as well as true and false. When I go to build, it thinks it can only return std::cv_status.
It should work right? Does it require the third parameter? The example I'm following doesn't use one.

As Bo says, there are 2 versions of the function. I'm going to assume there was a typo in the example and it meant to use the version of the function with three parameters, here's some working code, I don't know if it works in the same way as the example intended.
if (condition.wait_for(std::unique_lock<std::mutex>(mut), std::chrono::seconds(3), [] {return true; }))

Related

Why is my private member displayed as another type than it is defined as?

I'm currently working on a project in C++ and I'm just not allowed to push_back on my vector (compile error).
The method where everything seems to go wrong looks like this:
DetectionResult DetectionManager::Update(DetectionInput& input) const
{
std::vector<DetectionResultUnfiltered> results;
results.reserve(m_detectionModels.size());
for (auto& detectionModel : m_detectionModels)
(
std::future<void> future = std::async(std::launch::async, UpdateDetectionModelAsynchronously, detectionModel, &results, &input);
m_futures.push_back(future); // <-- Compile error only on this line
)
}
I think it is rather unimportant what exactly the other called method does and how those types are structured exactly. The only important thing should be that the field m_futures is of the type std::vector<std::future<void>>.
Even when hovering the m_futures in Visual Studio within that method, it clearly shows me that it is of the correct type (field) std::vector<std::future<void>> DetectionManager::m_futures.
But still the .push_back() call is underlined in red, and when hovered it shows the following error: no instance of overloaded function "std::vector<_Ty, _Alloc>::push_back [with _Ty=std::future<void>, _Alloc=std::allocator<std::future<void>>]" matches the argument list and object (the object has type qualifiers that prevent a match) - argument types are: (std::future<void>) - object type is: const std::vector<std::future<void>, std::allocator<std::future<void>>>
I'm pretty sure my vector is not really handled as a vector in this current case, because when auto completing the method calls on my vector I don't get even a suggestion for .push_back() or .emplace_back() or something like this. I think it is handled as an object of a type I imported from another library (opencv::mat or something like that), because at some point it was even shown like that when hovered.
And by the way,
the method call is not shown as an error when I do this:
(static_cast<std::vector<std::future<void>>>(m_futures)).push_back(future);
so by explicitly casting it to a vector it seems to work again.
I just don't know exactly what happens here. I've traced down and commented some includes to make sure nothing weird was included. And while doing that I figured out that I don't get any errors highlighted within the DetectionManager.h even when commenting out the #include (Even if not including ANYTHING in the .h at all, only the #include is needed when working with that type).
It doesn't even work on other vectors as well, so when implementing an example vector which only holds bools, I don't need to include the and everything looks right according to Visual Studio, which is weird enough since I didn't include or which I'm using as well.
Does anyone have any idea what it might be? Or how to track down this error?
Big thanks in advance!
As Borgleader correctly pointed out, the method was marked as const - but when pushing back, I am modifying the class field which is obviously not allowed.
The const was a leftover from an older design I just reworked and thus I completely forgot about it.
That paired with some other weird errors I had before (like the field being shown as a complete different type from some library I imported even though it was clearly declared as a vector) didn't help.
I still don't quite understand why my project is compiling when not including or within the header file at all even when I declare fields with those types, but at least that's not stopping me from building and running the program.

C++ Antlr Code stopped working (antlrcpp::Any)

I developed some ANTLR + LLVM parser code in spring. Since it is only a recreational project, I did not touch the code or see whether it compiles in the meantime. During that time, several system updates took place, which I assume caused my current problems:
When trying to compile the code today (with clang++), I suddenly got several error messages. Initially the std::any class was not found at all. I then played with "std=c++17" and "std=c++20" options. Now the main error (as I understand it) seems to be
error: no member named 'as' in 'std::any'
The error occurs whenever i do something like for instance
args.push_back(visit(*it).as<sarg>());
or, more stripped-down:
antlrcpp::Any myvar;
//...
myvar.as<some_type>();
I picked this up from Antlr tutorial codes where this seems to be the standard idiom to cast an antlrcpp::Any object to the type desired by the calling function.
I noticed that antlrcpp::Any apparently is merely a wrapper for std::any, which apparently really does not support this "as" method.
What can i do to make my code work again?

C++ Curious case of passing typename/datatype name/class name to thread constructor

I have returned to c++ after long years of Java/Node.js programming so, I am out of touch with the templates (I am working on that).
While revising concurrency, I accidentally stumbled upon the following case
class Test
{
};
int main()
{
std::thread t(Test);
}
What I was experimenting with was, what if I pass a non-callable object and then I would study the error and source code. But I accidentally passed the type name. The program compiled an ran with no issue and I was baffled.
Then I tried something more stupid
int main()
{
std::thread t1(int);
}
And somehow it worked as well.
Though these two cases compiled and ran properly. I don't get how.
If it tried t.join() or t1.join() I get following compilation error
t.join() cannot be resolved
I just simply just don't get what is happening in these two cases and how t.join() could not be resolved.
My research on it so far
I spend a significant amount of time trying to figure out how the compiler would have figured out whether the given value is callable. I came across this link: find out if a C++ object is callable
It made a lot of sense because of member detection idiom but when I checked the source of gcc it seemed it used std::_Bind_simple of functional header/library to figure this out. But it didn't solve my query.
Then, this post how std::thread constructor detects rvalue reference? asked the similar question but the answer made no sense to me.
Any sort of assistance will be very appreciated
Thanks to #Jaroda42 what I was doing was making a function declaration in local scope.
std::thread t(Test);
Where function being being t return type be std::thread and parameters being class type Test.
It was really stupid but this is what one get if one leaves a language for long time.

How do I prevent/suppress SIGFPE in C++?

I'm trying to convert a double to float as well as various integer types inside a dll, which is used as a Game Maker extension. I don't need a sensible result if the double doesn't fit the range of the target types, so I simply used a static_cast.
Everything works as intended when I call this code from my own test C++ application, but when it's called from Game Maker, range errors raise SIGFPE for some reason, which leads Game Maker to terminate my program with an error message.
I don't need sensible results for out-of-range conversions, but crashing is a no-no. I tried using llround instead of a cast, but it also raises the signal.
I also tried catching the signal myself by using signal(SIGFPE, SIG_IGN); right before the conversion, but it didn't change the behaviour at all. Maybe the ominous comment in the mingw signal.h has something to do with that: "SIGFPE doesn't seem to work?"
I checked the source code of a different dll used in a Game Maker extension, and the binary provided by the author performs simple cast conversions without a problem. When I compile the source myself however, the SIGFPE problem is present again. I am guessing that the author used a different compiler, but I'd prefer to stay with mingw if possible.
So, how do I either perform these conversions safely, or prevent the signal from being generated when I perform them with a simple cast? I'm using mingw-g++ 4.5.0 to compile at the moment.
Here's the function where the problem happens:
template<typename ValueType>
static double writeIntValue(double handle, double value) {
boost::shared_ptr<Writable> writable = handles.find<Writable>(handle);
if(writable) {
// Execution reaches this point
ValueType converted = static_cast<ValueType>(value);
// Execution doesn't reach this point if e.g. ValueType
// is short and value is 40000
writable->write(reinterpret_cast<uint8_t *>(&converted), sizeof(converted));
}
return 0;
}
The good solution is to perform the conversion correctly by ensuring that the source value is within the range of the target type before casting. So my code from the question could be corrected like this:
ValueType converted;
if(value >= std::numeric_limits<ValueType>::max()) {
converted = std::numeric_limits<ValueType>::max();
} else if(value <= std::numeric_limits<ValueType>::min()) {
converted = std::numeric_limits<ValueType>::min();
} else {
converted = static_cast<ValueType>(value);
}
Another option is to use numeric_cast from the Boost libraries, which throws an exception if the source value is out of range, so it has defined behaviour for all conversions.
The documentation of the Boost Numeric Conversion library contains some helpful information about how the standard defined certain conversions.
Thanks to rve for providing the correct suggestion in his answer, but unfortunately his example code is flawed, and I wanted to add some additional pointers that helped me.
Since you are using a DLL, are you sure the DLL is compiled in the same way as the program expects it? Maybe some 32/64 bit mismatch?
Also, SIGFPE can also be raised when there is an under/overflow when converting.
You can enable/disable the signal raised by this overflow by setting the mask using _FPU_SETCW (it's in fpu_control.h) My guess is that Game Maker enables this and your test program not.
I never tried this and I'm not sure mingw also has this but I hope this helps a little.
edit:
Why not making sure an overflow does not happen?
Something like:
if (value > std::numeric_limits<ValueType>::max())
{
value = std::numeric_limits<ValueType>::max();
}
else if (value < std::numeric_limits<ValueType>::min())
{
value = std::numeric_limits<ValueType>::min();
}
ValueType converted = value;
probably it's not related with conversion itself but with trying to access invalid memory (maybe stack corruptions or something like that). can you provide some code snippet?

Why does strlen() appear to return <void> in the VC++ debugger? [closed]

Closed. This question is off-topic. It is not currently accepting answers.
Want to improve this question? Update the question so it's on-topic for Stack Overflow.
Closed 14 years ago.
Improve this question
I have a string in C++ of type const char* passed as argument to strlen, but it returns void.
it goes like
strlen(astruct.string);
Thanks..
EDIT: Did some checking,
strlen("test");
still gives void.. why?
EDIT: Here's the image
http://img14.imageshack.us/img14/1808/strlen.png
Sorry for being unclear previously. Formatting was not working quite well. Anyway, the confusion was solved by both Evan Teran and Vlad Romascanu. Also take a look at Brian R. Bondy's answer.
Thanks. Feel free to close.
You are confused by the crappy debugger of visual studio 6.0. Don't rely on this. It likely couldn't get the return value due to inlining or something similar.
Print the value out to get the real value.
EDIT: Also, from your example, it seems that you may not be storing the result of strlen anyway. This also may be a reason why the debugger isn't seeing the return value. It's entirely possible that the compiler decided that it doesn't need to actually execute the strlen if you aren't using the value.
NOTE: at this point there is no real excuse for still using VC++ 6.0. It is an ancient compiler and IDE which is an embarrassingly poor c++ compiler. The newer versions of the visual c++ compiler are free (without the IDE), use them.
strlen is not of return type void, it's your debugger that is not giving the right message.
Why your debbuger is showing void?
The implementation of strlen that you are using is probably wrapped around a #define strlen someothername_strlen.
The debugger probably does not support #define properly or some other modifiers on the function.
You will have to do something like iLen = strlen("test") then check iLen in your watch.
Normally you can call functions in your watch. For example try to define the following function then call it in your watch:
int testFunc(char*)
{
return 5;
}
You will probably get 5 in your watch as a result.
Referring to your screen shot: your debugger is displaying <void> for strlen(...) when in fact it should display an error.
You cannot call methods and display their results in the debugger watch. The debugger will only display existing variables and data. It cannot invoke arbitrary methods on demand since the methods can alter the state of the program being debugged in ways that were not anticipated by either the author of the code nor by the debugger.
What you can do is, in your code, temporarily add:
size_t tmp_len = strlen(struc.string);
then compile, and add tmp_len to the watch.
strlen returns an integer, so I assume you mean it returns "0".
Also, the way that you specify your data type, I can't quite tell if it's a const char * or const char **. If it's the latter, then you need to make sure you're dereferencing the ** to a single *.
My guess is that the string starts with a null byte, which is why it's returning 0.
In C++, functions always return a value of the type they are declared to return. Since the strlen function declaration looks something like this:
size_t strlen(const char *);
the only thing it can possibly return is a size_t. The compiler uses this information at compile time to determine how to handle the return value when you call the function. The point here is that if the strlen function is declared as above, it cannot decide to return void sometimes and a value of type size_t other times.
This is generally a characteristic of statically typed languages like C++. In dynamically typed languages (Perl, Python, Ruby, PHP, etc) a function can decide to return a value of any type each time it is called.
It can't return void. Void is the lack of a return value, so you can't, err, return it.
How do you check for void anyway? Void isn't a value. Please demonstrate how you are getting void. Is it compile time or run time?
If you do in fact have a system where strlen is declared with a void return type, run as fast as you can in the other direction.