I used a code from here (Color folder) in Visual Studio 2013 to capture color data from Kinect v2. But when I want to run the code, these lines of code in util.h file causes a compile error:
#define ERROR_CHECK( ret ) \
if (FAILED(ret)){
\
std::stringstream ss; \
std::ss << "failed " #ret " " << std::hex << ret << std::endl; \
throw std::runtime_error(ss.str().c_str()); \
}
And my Visual Studio below draws ss a red line and is written: namespace "std" has no member "ss" below <<: expected a ";" and below throw: expected a declaration.
What is this part of code and how can I fix it?
This code is wrong, changing std::ss to ss should help:
#define ERROR_CHECK( ret ) \
if (FAILED(ret)) { \
\
std::stringstream ss; \
ss << "failed " #ret " " << std::hex << ret << std::endl; \
throw std::runtime_error(ss.str().c_str()); \
}
Another error in the code snippet you show that there was a line continuation missing after the if(statement).
Also ensure that <sstream> is included when using this.
The macro seems to be already fixed in the original code, but can be that other buggy versions of util.h are existing in the other sample folders.
It may not be what you wanted, but does your program work if you just comment every line? It is "just" a stringstream that only purpose (as far as I can see) is to print out when an error occurs. Replace it with some kind of printf() if you really want to see the output.
#define ERROR_CHECK( ret )
if (FAILED(ret)){
// std::stringstream ss;
// std::ss << "failed " #ret " " << std::hex << ret << std::endl;
// throw std::runtime_error(ss.str().c_str());
printf("Error : FAILED(ret)");
}
This way your code compiles but you do not have the original throw of an error IFF an error occurs
Related
I have a little error function that looks like this:
template<typename ErrorType>
void throwError(const std::string &file,
const std::string &function,
unsigned int line,
const std::string &msg = "") {
std::ostringstream errMsg;
errMsg << file << ":" << line << ":" << function << ":"
<< "\nError: " << msg << std::endl;
std::cerr << errMsg.str();
throw ErrorType(errMsg.str());
}
Then I have some macros that use the function:
#define INVALID_ARGUMENT_ERROR(msg) throwError<std::invalid_argument>(__FILE__, __func__, __LINE__, msg)
#define LOGIC_ERROR(msg) throwError<std::logic_error>(__FILE__, __func__, __LINE__, msg)
So I can do:
if (condition == bad)
LOGIC_ERROR("you did a bad");
But this is quite invonvenient when I want to add additional information in the error message, like values of numbers for example.
What would be a good way of modifying this function so that it enables me to use a stream instead of a string? So I want do be able to do:
if (condition == bad)
LOGIC_ERROR("you did a bad because condition \"" << condition << " != " << bad);
I've tried changing the std::string string msg to a std::ostringstream which does not work.
If you're willing to change the syntax slightly then a simple helper macro could be used. Given your current function template...
template<typename ErrorType>
void throwError(const std::string &file,
const std::string &function,
unsigned int line,
const std::string &msg = "")
{
std::ostringstream errMsg;
errMsg << file << ":" << line << ":" << function << ":"
<< "\nError: " << msg << std::endl;
std::cerr << errMsg.str();
throw ErrorType(errMsg.str());
}
you can then define...
#define THROW_HELPER(ex_type) \
for (std::stringstream ss; true; throwError<ex_type>(__FILE__, __func__, __LINE__, ss.str())) \
ss
#define INVALID_ARGUMENT_ERROR THROW_HELPER(std::invalid_argument)
#define LOGIC_ERROR THROW_HELPER(std::logic_error)
These can then be used as, e.g...
LOGIC_ERROR << "extra messages go here";
Note that currently two separate std::stringstream instances are created in the process of throwing an exception so the code shown should probably be 'compacted' a bit to prevent that [left as an exercise :-) ].
I propose a different option: libfmt!
#define LOGIC_ERROR(...) \
throwError<std::logic_error>(__FILE__, __func__, __LINE__, fmt::format(__VA_ARGS__))
Usage:
if (condition == bad)
LOGIC_ERROR("you did a bad because condition {} != {}", condition, bad);
The downside of this approach is that fmt::format will throw an exception if the format string is invalid. You could instead check it at compile-time using FMT_STRING() macro:
#define LOGIC_ERROR(string) \
throwError<std::logic_error>(__FILE__, __func__, __LINE__, string)
#define LOGIC_ERROR_P(string, ...) \
throwError<std::logic_error>(__FILE__, __func__, __LINE__, \
fmt::format(FMT_STRING(string), __VA_ARGS__))
Here I've created two versions of LOGIC_ERROR with and without extra parameters. It possible to have a single a single macro dispatch between those two depending on the number of arguments, but that's left as an exercise to the reader.
I'm trying to use a macro to queue up a single log line locally in an ostringstream and then dump the entire contents of that ostringstream when the line is over. I want to still use stream insert syntax, however. So I want to turn a log line like this:
std::cerr << "Some error in my function. Code is " << errCode << " exiting" << std::endl;
...into this
SERR("Some error in my function. Code is " << errCode << " exiting);
I've got something simple that works well. That is, until I put it in an if-else statement. Obviously my macro is bad but I am at a loss as to what to do.
Here is a small sample program, hacked up to illustrate the problem.:
#include <iostream>
#include <sstream>
#define SERR(x) { std::ostringstream _s; ; _s << x << std::endl; std::cerr << _s.str(); }
int main()
{
std::cout << "Hello World!\n";
bool val = false;
if (val)
SERR("No error");
else
SERR("Error");
}
The error message I get from the compiler in this sample is:
1>c:\users\joe\source\repos\consoleapplication5\consoleapplication5\consoleapplication5.cpp(15):
error C2181: illegal else without matching if
Any ideas what I've got wrong here?
(Note I'm not in a place where I can use a 3rd Party logging solution now so it's got to be something simple like this. I could just leave all this as normal std::cerr/std::cout/std::clog messages, if I had to but I'd prefer something simple to minimize the chances of interleaving of log messages from my multithreaded app.)
Just try to expand it and see what you get:
#include <iostream>
#include <sstream>
int main()
{
std::cout << "Hello World!\n";
bool val = false;
if (val)
{ std::ostringstream _s; ; _s << "No error" << std::endl; std::cerr << _s.str(); };
else
{ std::ostringstream _s; ; _s << "Error" << std::endl; std::cerr << _s.str(); };
}
Notice how { } block is terminated with ;?
If you need a macro, you should always write it using do { } while (0) like this:
#define SERR(x) \
do { \
std::ostringstream _s; \
_s << (x) << std::endl; \
std::cerr << _s.str(); \
} while (0)
Not only this solves your issue, but also make it mandatory to add ; after the macro. Otherwise people could use it two ways:
SERR("foo") // without ;
...
SERR("bar"); // with ;
This question already has answers here:
c popen won't catch stderr
(2 answers)
Closed 6 years ago.
I have a directory that when i run a ls command on, I know that it spits out an error like so:
ls: reading directory /mydir: Input/output error
I want to be able to detect that there was an IO error in my code.
This is what i've tried:
void readLs(const std::string& name)
{
stringstream ss;
ss << "ls " << name;
FILE* apipe = popen(ss.str().c_str(), "r");
if(apipe == NULL)
{
cout << "Error opening popen" << endl;
return;
}
char line[256];
cout << __FILE__ << " " << __LINE__ << endl; //This is line 46
while ( fgets( line, 256 , apipe) )
{
string temp(line);
cout << "This is line: " << temp << endl;
memset(line, 0, 256);
}
cout << __FILE__ << " " << __LINE__ << endl; //This is line 53
pclose(apipe);
}
test.cpp 46
ls: reading directory /mydir: Input/output error
test.cpp 53
The error message prints out to the screen but i don't get the error message when reading from the pipe.
Thanks,
Conversely, reading from the stream reads the command's
standard output
http://man7.org/linux/man-pages/man3/popen.3.html
You are reading the standard input of the invoked program, which is empty. The error message is written to the standard output. Try executing ls 2>&1.
When I test a method using
BOOST_CHECK_NO_THROW( method_to_test() );
and an exception is thrown, it displays that an exception was thrown, but never the exception's message like this:
test.cpp(14): error in "test": incorrect exception my_exception is caught
Is it possible to print the exception message as well, i.e. the string returned by my_exception.what()? my_exception is derived from std::exception and overloads what().
I found myself annoyed by the same problem with BOOST_REQUIRE_NO_THROW. I solved it by simply removing the BOOST_REQUIRE_NO_THROW. This results in output like:
unknown location(0): fatal error in "TestName": std::runtime_error: Exception message
and aborts the test (but goes on with the next text), which is what I wanted. This doesn't help much if you wanted to use BOOST_CHECK_NO_THROW or BOOST_WARN_NO_THROW, though.
I read a bit in the boost headers and redefined BOOST_CHECK_NO_THROW_IMPL in my own header file I use in the project to redefine the boost behavior. Now it looks like this:
#ifndef _CATCH_BOOST_NO_THROW_H_
#define _CATCH_BOOST_NO_THROW_H_
#include <boost/test/unit_test.hpp>
#include <sstream>
#include <string>
#define BOOST_CHECK_NO_THROW_IMPL( S, TL ) \
try { \
S; \
BOOST_CHECK_IMPL( true, "no exceptions thrown by " BOOST_STRINGIZE( S ), TL, CHECK_MSG ); } \
catch( const std::exception & e ) { \
std::stringstream ss; \
ss << std::endl \
<< "-----------------------------------------------" << std::endl \
<< "test case: " << boost::unit_test::framework::current_test_case().p_name << std::endl \
<< std::endl << "exception message: " << e.what() << std::endl; \
BOOST_TEST_MESSAGE(ss.str()); \
BOOST_CHECK_IMPL( false, "exception thrown by " BOOST_STRINGIZE( S ), TL, CHECK_MSG ); \
} \
catch( ... ) { \
std::stringstream ss; \
ss << std::endl \
<< "-----------------------------------------------" << std::endl \
<< "test case: " << boost::unit_test::framework::current_test_case().p_name << std::endl \
<< std::endl << "exception message : <unknown exception>" << std::endl; \
BOOST_TEST_MESSAGE(ss.str()); \
BOOST_CHECK_IMPL( false, "exception thrown by " BOOST_STRINGIZE( S ), TL, CHECK_MSG ); \
} \
/**/
#define BOOST_WARN_NO_THROW( S ) BOOST_CHECK_NO_THROW_IMPL( S, WARN )
#define BOOST_CHECK_NO_THROW( S ) BOOST_CHECK_NO_THROW_IMPL( S, CHECK )
#define BOOST_REQUIRE_NO_THROW( S ) BOOST_CHECK_NO_THROW_IMPL( S, REQUIRE )
#endif // _CATCH_BOOST_NO_THROW_H_
The disadvantages are: It works as long as there are no changes in BOOST_*_NO_THROW
and
the exception message will be printed before it is marked as error in the test output. That looks in the first place a bit pitty, that's why I group the output by writing "---" to the outstream to enhance the reading. But code after BOOST_CHECK_IMPL will never be reached.
The solution above work quite nice for me. Feel free to use to, if you got the same whish =)
(Using CDash for ctest output, don't forget to increase the test output limit, or simple disable the limit: http://web.archiveorange.com/archive/v/5y7PkVuHtkmVcf7jiWol )
Solution 1.
Use a wrapper method that catches the exception, then prints the error message and then re-throws so that BOOST can report it:
void method_to_test(int s)
{
if(s==0)
throw std::runtime_error("My error message");
}
void middle_man(int x)
{
try
{
method_to_test(x);
}catch(std::exception& e)
{
std::stringstream mes;
mes << "Exception thrown: " << e.what();
BOOST_TEST_MESSAGE(mes.str());// BOOST_ERROR(mes.str());
throw;
}
}
Then your test case would read:
BOOST_AUTO_TEST_CASE(case1)
{
BOOST_CHECK_NO_THROW( middle_man(0) );
}
A drawback of this approach is that you will need to use a different middle_man function for every method_to_test.
Solution 2.
Use decorators, see this answer,
to do just what a wrapper from the previous solution would do.
template <class> struct Decorator;
template<class R,class ... Args>
struct Decorator<R(Args ...)>
{
std::function<R(Args ...)> f_;
Decorator(std::function<R(Args ...)> f):
f_{f}
{}
R operator()(Args ... args)
{
try
{
f_(args...);
}catch(std::exception& e)
{
std::stringstream mes;
mes << "Exception thrown: " << e.what();
BOOST_TEST_MESSAGE(mes.str());
throw;
}
}
};
template<class R,class ... Args>
Decorator<R(Args...)> makeDecorator(R (*f)(Args ...))
{
return Decorator<R(Args...)>(std::function<R(Args...)>(f));
}
then your test cases would look like this:
BOOST_AUTO_TEST_CASE(case2)
{
BOOST_CHECK_NO_THROW( makeDecorator(method_to_test)(0) );
BOOST_CHECK_NO_THROW( makeDecorator(another_method_to_test)() );
}
Is there easily embeddable C++ test lib with a friendly license? I would like a single header file. No .cpp files, no five petabytes of includes. So CppUnit and Boost.Test are out.
Basically all I want is to drop single file to project tree, include it and be able to write
testEqual(a,b)
and see if it fail. I'd use assert, but it doesn't work in non-debug mode and can't print values of a and b, and before rewriting assert I'd rather search existing library.
I'm tempted to say "write your own", which is what I have done. On the other hand, you might want to reuse what I wrote: test_util.hpp and test_util.cpp. It is straightforward to inline the one definition from the cpp file into the hpp file. MIT lisence. I have also pasted it into this answer, below.
This lets you write a test file like this:
#include "test_util.hpp"
bool test_one() {
bool ok = true;
CHECK_EQUAL(1, 1);
return ok;
}
int main() {
bool ok = true;
ok &= test_one();
// Alternatively, if you want better error reporting:
ok &= EXEC(test_one);
// ...
return ok ? 0 : 1;
}
Browse around in the tests directory for more inspiration.
// By Magnus Hoff, from http://stackoverflow.com/a/9964394
#ifndef TEST_UTIL_HPP
#define TEST_UTIL_HPP
#include <iostream>
// The error messages are formatted like GCC's error messages, to allow an IDE
// to pick them up as error messages.
#define REPORT(msg) \
std::cerr << __FILE__ << ':' << __LINE__ << ": error: " msg << std::endl;
#define CHECK_EQUAL(a, b) \
if ((a) != (b)) { \
REPORT( \
"Failed test: " #a " == " #b " " \
"(" << (a) << " != " << (b) << ')' \
) \
ok = false; \
}
static bool execute(bool(*f)(), const char* f_name) {
bool result = f();
if (!result) {
std::cerr << "Test failed: " << f_name << std::endl;
}
return result;
}
#define EXEC(f) execute(f, #f)
#endif // TEST_UTIL_HPP
Try google-test https://github.com/google/googletest/
it's really light weight, cross platform and simple.