Is there a way to ensure lazy evaluation of BOOST_TESTs message? - c++

Is it possible to ensure that the message macro parameter of BOOST_TEST is only evaluated, if the check actually fails. Lazy evaluation seems to happen for human readable output format, but not for JUnit output format. Can I somehow make lazy evaluation work reliably for all output types?
MCVE
#define BOOST_TEST_MODULE my_module
#include <boost/test/included/unit_test.hpp>
#include <string>
struct S
{
std::string m_value;
};
S* f(void)
{
return nullptr;
}
BOOST_AUTO_TEST_CASE(foo_test)
{
S* result = f();
BOOST_TEST(result == nullptr, "f() should return nullptr but returned a object with m_value = " << result->m_value);
}
This code works fine if I use human readable output format (--log_format=HRF command line option for executable). Using JUnit output (--log_format=JUNIT command line option) results in a access error, since the program attempts to get the size of a string at address 0.
This is a bit unexpected, since I'd assume the BOOST_TEST macro would work similar to this
// not the real macro, but one that works in a way I'd expect it to work
#define BOOST_TEST(condition, message) if (!(condition)) { \
some_output_stream << "The following test failed: " << #condition << std::endl \
<< "Message: " << message; \
}
Tested configurations:
boost 1.75.0
Visual Studio 2017/2019 or g++ 8.x (Win 10 / Ubuntu 18)
64 bit

Related

Simplest C++ Example to verify my compiler is c++14 compliant?

I am taking a class next week on C++11/14 and need to verify that my design tools are up to date and can actually compile C++11/14.
What is the simplest piece of code that I can put together to verify that I can actually compile and execute C++11/14 code on my Linux box? I know I need GCC 4.9.X or better, but I want to just be sure that everything is jiving before I show up.
Thanks for the help.
You can initially compile with -std=c++14. If your gcc (or clang) is not c++14 compliant then compilation will fail (due to uknown flag) :
g++: error: unrecognized command line option '-std=c++14'
Regarding feature availability (querying the existence of specific features), you can perform feature testing. An example document can be found here : it all boils down to the use of macros to test the availability of the specified feature (therein you can also find what features to look for).
So even if you want to build with several compilers you can write code like this (naive example follows) :
#if __cpp_constexpr
constexpr
#endif
int triple(int k) { return 3*k; } // compiles with c++98 as well
which is how cross platform developing overcomes the joys of supporting multiple compilers and their versions (more elaborate examples would show supporting sth one way in gcc and another way in cl due to different speed of standard implementation)
The __cplusplus macro contains the C++ standard that the compiler is using. Each version of C++ has a specific value for this define. These may (counter intuitively) not match exactly with the name of the standard, so you can use gcc to determine what the values are. For example:
#include <stdio.h>
int main()
{
printf("%ld\n", __cplusplus);
}
Compiled like so:
g++ -std=c++98 file.cpp
g++ -std=c++11 file.cpp
g++ -std=c++14 file.cpp
Gives the following respectively when run:
199711
201103
201300
You can then use the predefined macros to generate errors if the value you're looking for isn't available. For example:
#if __cplusplus < 201300
#error I require C++14 for this code, so die.
#endif
// ...
Then g++ -std=c++11 file.cpp will fail compilation.
To be sure it works you can simple try to compile some code available only since c++14. For example
#include <iostream>
#include <tuple>
#include <functional>
auto f() // this function returns multiple values
{
int x = 5;
return std::make_tuple(x, 7); // not "return {x,7};" because the corresponding
// tuple constructor is explicit (LWG 2051)
}
int main()
{
// heterogeneous tuple construction
int n = 1;
auto t = std::make_tuple(10, "Test", 3.14, std::ref(n), n);
n = 7;
std::cout << "The value of t is " << "("
<< std::get<0>(t) << ", " << std::get<1>(t) << ", "
<< std::get<2>(t) << ", " << std::get<3>(t) << ", "
<< std::get<4>(t) << ")\n";
// function returning multiple values
int a, b;
std::tie(a, b) = f();
std::cout << a << " " << b << "\n";
}
If this does work than you have the right setup :D Hope this helps
Compiling with flag -std=c++11 or -std=c++14 as per Nikos answer can determine if the compiler supports these standards.
Small examples using C++11 and C++14:
For C++11, you could try compiling auto with -std=c++11:
#include <memory>
using namespace std;
int main()
{
auto p1 = make_shared<int>(42);
// use p1
}
For C++14, try using auto as return type with -std=c++14:
auto func(int i)
{
return [i=std::move(i)](int b){return b+i;};
}
int main()
{
int num = func(3)(5);
// use num
}

log4cxx access exception using << operator and macro

I tried to encapsulate using log4cxx in our code by using #define directives and macros. The code compiles but when running I get Access violation, because I believe the stream object is not correctly initialized.
The header file which tries to make log4cxx pluggable looks like this:
#ifdef USE_LOG4CXX
#include "log4cxx/logger.h"
#define LOG_DEBUG(msg) LOG4CXX_DEBUG(logger, msg)
#define LOG_INFO(msg) LOG4CXX_INFO(logger, msg)
#define LOG_WARN(msg) LOG4CXX_WARN(logger, msg)
#define LOG_ERROR(msg) LOG4CXX_ERROR(logger, msg)
#define LOGGER_DECL static const log4cxx::LoggerPtr logger
#define LOGGER_INIT(source,name) const log4cxx::LoggerPtr source::logger = log4cxx::Logger::getLogger(#name);
#else // use some other log method, e.g. stdout which worked fine
The .cpp file does the logging like this:
LOG_INFO("state(): " << old_state << " ==> " << new_state );
The preprocessor expanded the .cpp file to:
{ if (logger->isInfoEnabled()) { ::log4cxx::helpers::MessageBuffer oss_; logger->forcedLog(::log4cxx::Level::getInfo(), oss_.str(oss_ << "state(): " << state_ << " ==> " << new_state), ::log4cxx::spi::LocationInfo("c:\\dev\\ezx-capi\\iserver-api\\iserver_client.cpp", __FUNCSIG__ , 190)); }};
The data type of old_state and new_state are int.
When running, the application fails on:
std::basic_ostream<char>& operator<<(CharMessageBuffer& os, const V& val) {
return ((std::basic_ostream<char>&) os) << val;
}
In the debugger, the problem looks like the CharMessageBuffer object has a std::basic_streambuf member which is not initialized, and so when it goes to append the value, it dies. (I'm not sure about that explanation though.)
Drilling all the way down, it dies in std::basic_ostream:
_Myt& __CLR_OR_THIS_CALL operator<<(int _Val)
{ // insert an int
ios_base::iostate _State = ios_base::goodbit;
const sentry _Ok(*this); // dies right here, in the constructor
Anyway, I realize this has something to do with how I am using a macro to invoke LOG4CXX. (When I had the USE_LOG4FXX not defined, all the log statements were going to std::cout and it worked fine.)
UPDATE
One other piece of information - it seems that this is only failing when I invoke the logging from within a static library. If I use the same (or similar) macro from an EXE project, it doesn't fail at all. So I can't seem to replicate this problem in some kind of separate test application.
The problem was caused by the way the enum was interpreted. The compiler invoked the template << operator, instead of the version of the << operator which took an int type. What was even stranger (to me), was that a test app I wrote to see whether the enum data type was the problem worked without issue, i.e.:
ezx::net::client_state::state mystate = ezx::net::client_state::connecting;
LOG_INFO("this should show new state" << mystate);
This did not throw any error, and took a different code path than the same code above.
The conclusion I reached was that the log4cxx implementation of this operator is fragile, in that it will compile fine, but then fail unexpectedly at runtime, depending on whether the datatype is dispatched to the correct version of the operator or not.

xlocale broken on OS X?

I have a simple program that tests converting between wchar_t and char using a series of locales passed to it on the command line. It outputs a list of the conversions that fail by printing out the locale name and the string that failed to convert.
I'm building it using clang and libc++. My understanding is that libc++'s named locale support is provided by the xlocale library on OS X.
I'm seeing some unexpected failures, as well as some instances where conversion should fail, but doesn't.
Here's the program.
#warning call this program like: "locale -a | ./a.out" or pass \
locale names valid for your platform, one per line via standard input
#include <iostream>
#include <codecvt>
#include <locale>
#include <array>
template <class Facet>
class usable_facet : public Facet {
public:
// FIXME: use inheriting constructors when available
// using Facet::Facet;
template <class ...Args>
usable_facet(Args&& ...args) : Facet(std::forward<Args>(args)...) {}
~usable_facet() {}
};
int main() {
std::array<std::wstring,11> args = {L"a",L"é",L"¤",L"€",L"Да",L"Ψ",L"א",L"আ",L"✈",L"가",L"𐌅"};
std::wstring_convert<usable_facet<std::codecvt_utf8<wchar_t>>> u8cvt; // wchar_t uses UCS-4/UTF-32 on this platform
int convert_failures = 0;
std::string line;
while(std::getline(std::cin,line)) {
if(line.empty())
continue;
using codecvt = usable_facet<std::codecvt_byname<wchar_t,char,std::mbstate_t>>;
std::wstring_convert<codecvt> convert(new codecvt(line));
for(auto const &s : args) {
try {
convert.to_bytes(s);
} catch (std::range_error &e) {
convert_failures++;
std::cout << line << " : " << u8cvt.to_bytes(s) << '\n';
}
}
}
std::cout << std::string(80,'=') << '\n';
std::cout << convert_failures << " wstring_convert to_bytes failures.\n";
}
Here are some examples of correct output
en_US.ISO8859-1 : €
en_US.US-ASCII : ✈
Here's an example of output that is not expected
en_US.ISO8859-15 : €
The euro character does exist in the ISO 8859-15 charset and so this should not be failing.
Here are examples of output that I expect but do not receive
en_US.ISO8859-15 : ¤
en_US.US-ASCII : ¤
This is the currency symbol that exists in ISO 8859-1 but was removed and replaced with the euro symbol in ISO 8859-15. This conversion should not be succeeding, but no error is being signaled. When examining this case further I find that in both cases '¤' is being converted to 0xA4, which is the ISO 8859-1 representation of '¤'.
I'm not using xlocale directly, only indirectly via libc++. Is xlocale on Mac OS X simply broken with bad locale definitions? Is there a way to fix it? Or are the issues I'm seeing a result of something else?
I suspect you are seeing problems with the xlocale system. A bug report would be most appreciated!
I don't know why you're expecting wchar_t to be UTF-32 or where you heard that "OS X's convention that wchar_t is UTF-32." That is certainly incorrect. wchar_t are only 16 bits wide.
See http://en.wikipedia.org/wiki/Wide_character for more information about wchar_t.

Is there a way to get function name inside a C++ function?

I want to implement a function tracer, which would trace how much time a function is taking to execute. I have following class for the same:-
class FuncTracer
{
public:
FuncTracer(LPCTSTR strFuncName_in)
{
m_strFuncName[0] = _T('\0');
if( strFuncName_in ||
_T('\0') != strFuncName_in[0])
{
_tcscpy(m_strFuncName,strFuncName_in);
TCHAR strLog[MAX_PATH];
_stprintf(strLog,_T("Entering Func:- <%s>"),m_strFuncName);
LOG(strLog)
m_dwEnterTime = GetTickCount();
}
}
~FuncTracer()
{
TCHAR strLog[MAX_PATH];
_stprintf(strLog,_T("Leaving Func:- <%s>, Time inside the func <%d> ms"),m_strFuncName, GetTickCount()-m_dwEnterTime);
LOG(strLog)
}
private:
TCHAR m_strFuncName[MAX_PATH];
DWORD m_dwEnterTime;
};
void TestClass::TestFunction()
{
// I want to avoid writing the function name maually..
// Is there any macro (__LINE__)or some other way to
// get the function name inside a function ??
FuncTracer(_T("TestClass::TestFunction"));
/*
* Rest of the function code.
*/
}
I want to know if there is any way to get the name of the function from inside of a function? Basically I want the users of my class to simply create an object the same. They may not pass the function name.
C99 has __func__, but for C++ this will be compiler specific. On the plus side, some of the compiler-specific versions provide additional type information, which is particularly nice when you're tracing inside a templatized function/class.
MSVC: __FUNCTION__, __FUNCDNAME__, __FUNCSIG__
GCC: __func__, __FUNCTION__, __PRETTY_FUNCTION__
Boost library has defined macro BOOST_CURRENT_FUNCTION for most C++ compilers in header boost/current_function.hpp. If the compiler is too old to support this, the result will be "(unknown)".
VC++ has
__FUNCTION__ for undecorated names
and
__FUNCDNAME__ for decorated names
And you can write a macro that will itself allocate an object and pass the name-yelding macro inside the constructor. Smth like
#define ALLOC_LOGGER FuncTracer ____tracer( __FUNCTION__ );
C++20 std::source_location::function_name
main.cpp
#include <iostream>
#include <string_view>
#include <source_location>
void log(std::string_view message,
const std::source_location& location = std::source_location::current()
) {
std::cout << "info:"
<< location.file_name() << ":"
<< location.line() << ":"
<< location.function_name() << " "
<< message << '\n';
}
int f(int i) {
log("Hello world!"); // Line 16
return i + 1;
}
int f(double i) {
log("Hello world!"); // Line 21
return i + 1.0;
}
int main() {
f(1);
f(1.0);
}
Compile and run:
g++ -ggdb3 -O0 -std=c++20 -Wall -Wextra -pedantic -o source_location.out source_location.cpp
./source_location.out
Output:
info:source_location.cpp:16:int f(int) Hello world!
info:source_location.cpp:21:int f(double) Hello world!
so note how the call preserves caller information, so we see the desired main call location instead of log.
I have covered the relevant standards in a bit more detail at: What's the difference between __PRETTY_FUNCTION__, __FUNCTION__, __func__?
Tested on Ubuntu 22.04, GCC 11.3.
I was going to say I didn't know of any such thing but then I saw the other answers...
It might interest you to know that an execution profiler (like gprof) does exactly what you're asking about - it tracks the amount of time spent executing each function. A profiler basically works by recording the instruction pointer (IP), the address of the currently executing instruction, every 10ms or so. After the program is done running, you invoke a postprocessor that examines the list of IPs and the program, and converts those addresses into function names. So I'd suggest just using the instruction pointer, rather than the function name, both because it's easier to code and because it's more efficient to work with a single number than with a string.

How to find the name of the current function at runtime?

After years of using the big ugly MFC ASSERT macro, I have finally decided to ditch it and create the ultimate ASSERT macro.
I am fine with getting the file and line number, and even the expression that failed. I can display a messagebox with these in, and Abort/Retry/Cancel buttons.
And when I press Retry the VS debugger jumps to the line containing the ASSERT call (as opposed to the disassembly somewhere like some other ASSERT functions). So it's all pretty much working.
But what would be really cool would be to display the name of the function that failed.
Then I can decide whether to debug it without trying to guess what function it's in from the filename.
e.g. if I have the following function:
int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
ASSERT(lpCreateStruct->cx > 0);
...
}
Then when the ASSERT fires, the messagebox would show something like:
Function = CMainFrame::OnCreate
So, what's the simplest way of finding out the current function name, at runtime?
It should not use MFC or the .NET framework, even though I do use both of these.
It should be as portable as possible.
Your macro can contain the __FUNCTION__ macro.
Make no mistake, the function name will be inserted into the expanded code at compile time, but it will be the correct function name for each call to your macro. So it "seems like" it happens in run-time ;)
e.g.
#define THROW_IF(val) if (val) throw "error in " __FUNCTION__
int foo()
{
int a = 0;
THROW_IF(a > 0); // will throw "error in foo()"
}
The C++ preprocessor macro __FUNCTION__ gives the name of the function.
Note that if you use this, it's not really getting the filename, line number, or function name at runtime. Macros are expanded by the preprocessor, and compiled in.
Example program:
#include <iostream>
void function1()
{
std::cout << "my function name is: " << __FUNCTION__ << "\n";
}
int main()
{
std::cout << "my function name is: " << __FUNCTION__ << "\n";
function1();
return 0;
}
output:
my function name is: main
my function name is: function1
There's no standard solution. However, BOOST_CURRENT_FUNCTION is portable for all practical purposes. The header does not not depend on any of the other Boost headers, so can be used standalone if the overhead of the whole library is unacceptable.
__FUNCTION__ or __FUNC__ or __PRETTY_FUNCTION__
http://msdn.microsoft.com/en-us/library/b0084kay(VS.80).aspx
http://gcc.gnu.org/onlinedocs/gcc/Function-Names.html
In GCC you can use the __PRETTY_FUNCTION__ macro.
Microsoft also have an equivalent __func__ macro although I don't have that available to try.
e.g. to use __PRETTY_FUNCTION__ putting something like this at the beginning of your functions and you'll get a complete trace
void foo(char* bar){
cout << __PRETTY_FUNCTION__ << std::endl
}
which will output
void foo(char* bar)
You also have the __FILE__ and __LINE__ macros available under all standard c/c++ compilers if you want to output even more information.
In practice I have a special debugging class which I use instead of cout. By defining appropriate environment variables I can get a full program trace. You could do something similar. These macros are incredibly handy and it's really great to be able to turn on selective debugging like this in the field.
EDIT: apparently __func__ is part of the standard? didn't know that. Unfortunately, it only gives the function name and not the parameters as well. I do like gcc's __PRETTY_FUNC__ but it's not portable to other compilers.
GCC also supports __FUNCTION__.
You can use the __FUNCTION__ macro which at compile time will be expanded to the name of the function.
Here's an example of how to use it in an assert macro.
#define ASSERT(cond) \
do { if (!(cond)) \
MessageBoxFunction("Failed: %s in Function %s", #cond, __FUNCTION__);\
} while(0)
void MessageBoxFunction(const char* const msg, ...)
{
char szAssertMsg[2048];
// format args
va_list vargs;
va_start(vargs, msg);
vsprintf(szAssertMsg, msg, vargs);
va_end(vargs);
::MessageBoxA(NULL, szAssertMsg, "Failed Assertion", MB_ICONERROR | MB_OK);
}
C++20 std::source_location::function_name
No macros are needed now that we have proper standardization:
main.cpp
#include <iostream>
#include <string_view>
#include <source_location>
void log(std::string_view message,
const std::source_location& location = std::source_location::current()
) {
std::cout << "info:"
<< location.file_name() << ":"
<< location.line() << ":"
<< location.function_name() << " "
<< message << '\n';
}
int f(int i) {
log("Hello world!"); // Line 16
return i + 1;
}
int f(double i) {
log("Hello world!"); // Line 21
return i + 1.0;
}
int main() {
f(1);
f(1.0);
}
Compile and run:
g++ -ggdb3 -O0 -std=c++20 -Wall -Wextra -pedantic -o source_location.out source_location.cpp
./source_location.out
Output:
info:source_location.cpp:16:int f(int) Hello world!
info:source_location.cpp:21:int f(double) Hello world!
so note how the call preserves caller information, so we see the desired main call location instead of log.
I have covered the relevant standards in a bit more detail at: What's the difference between __PRETTY_FUNCTION__, __FUNCTION__, __func__?
Tested on Ubuntu 22.04, GCC 11.3.
you can easily use func.
it will take back you current function name at runtime which raised the exception.
usage:
cout << __func__ << ": " << e.what();