How can I implement assert macro as a method? - c++

I want implement assert macro as a method in C++ like .NET Framewrk.
For example in C# we can invoke assert method like this:
Debug.Assert(index > -1);
and I want implement assert something like this:
#include <assert.h>
class debug
{
public:
static void my_asset(<condition>) // like assert macro
{
// ?
}
};
When using this class:
debug::my_asset(index > -1); // Actually should be called assert(index > -1);
Thanks
Edit:
I want when invoking debug::my_asset(index > -1);, It shows correct file name and line number, and it works like C++ asset macro.

There are several features of assert assert (in <assert.h> or <cassert>) that are of interest:
that when you're compiling a release build, the assert tests aren't evaluated at all.
the error message printed when an assertion fails can tell you the file and line number where your assertion failed
it can also tell you the exact code that failed.
You can't do these in C++ without using a macro.

The only way to get the line number, file, and text version is via macro. However:
#include <assert.h>
class debug
{
public:
static void my_assert(bool passed, const char* assert, const char* file, long line)
{
if (passed == false)
std::cout<<"failed assert "<<assert<<" in "<<file<<" at "<<line<<".\n";
}
#ifdef NDEBUG
#define myassert(x) my_assert(true, "", "", 0)
#else
#define myassert(x) my_assert(x, #x , __FILE__, __LINE__ )
#endif
};
int main() {
debug::myassert(sizeof(int)==4);
return 0,
}
This code works in an oddball way. The first x is the assert expression itself, evaluating to true or false, to tell my_assert what to do. The #x is a magic preprocessor command that makes a char* version of x, so we can display it. __FILE__ is replaced with the filename, and __LINE__ is replaced with the line number. (Since it's a macro, it has the same line number as the calling function).
When you type debug::myassert(sizeof(int)==4);, the preprocessor says "I know what myassert(whatever) is!" and replaces it. So it replaces it all with: debug::my_assert(sizeof(int)==4, "sizeof(int)==4", "main.cpp", 27);, which is a valid line of code. So if sizeof(int) is 8 for instance (it is on some machines), the first parameter is false, and the line is displayed "failed assert sizeof(int)==4 in main.cpp at 27."

static void my_asset(bool cond) // like assert macro
{
::assert(cond);
}
Doesn't work?

You could
void debug::my_assert(bool cond) {
ASSERT(cond);
}
This would work in that it would cause an exception when the assertion failed.
It's a little less helpful than the macro because my_assert can't see what the condition was that failed -- you'll get an assertion failure but no useful explanation (though you'll get an accurate stack trace in a debugger).
Also see Ken's reasons why a macro is more helpful.

Related

Is it possible to pack __FILE__, __LINE__, __FUNCTION__ into #error, #warning strings?

I use #warning to mark some unfinished functions, so that when someone compiles the code later, they see a hint that they still need to continue to implement. for example:
class HttpDownloadJobAndroid : public HttpDownloadJob
{
public:
virtual void Download() override
{
#warning "Please complete the implementation of the function : HttpDownloadJobAndroid::Download"
Finished = true;
Success = false;
}
};
This works great, but there is a small problem that every time I copy and paste this warning into a new function, I always need to change the function name in it. This will undoubtedly affect some work efficiency. So I thought, is it possible to pack a C++ macro like __FUNCTION__ into this string so I can copy this warning anywhere.
#define _ME_PP_TEXT(Expr) #Expr
#define ME_PP_TEXT(Expr) _ME_PP_TEXT(Expr)
// not work
#warning "Please complete the implementation of the function : " __FUNCTION__
// not work too...
#warning "Please complete the implementation of the function : " ME_PP_TEXT(__FUNCTION__)
I've tried this method, but it doesn't seem to work.
Of course, if there are other better solutions, please teach me, thank you.
my compiler is Clang 5.0, target platform is android.

How to view Macro definition value in executable

Been years since I've coded in C/C++ so sorry about the newbie'ish question. I have codebase that compiles differently based upon configurations that are defined via #defines, which can be provided as args to the makefile. Is there a way to encode these #defines so I can look at an executable and see what the define was - e.g.
int main() {
#ifdef CONFIG_A
init_config_a();
#endif
#ifdef CONFIG_B
init_config_b();
#endif
}
#ifdef CONFIG_A
void init_config_a() {
// do something
}
#endif
#ifdef CONFIG_B
void init_config_b() {
// do something for B
}
#endif
How can I tell if a given executable was created with config A or config B. One hack is to look for symbols that are only compiled based upon the definitions (e.g. init_config_a) but that's pretty ugly.
EDIT: Sorry I neglected an important piece of info: the program is actually compiled to run on an embedded system so I can't easily just add a switch or some other mechanism to run the program locally.
Well, your question is not really precise on how you really want to get the information once you have the binary. As solution that does not involved disassembly would be having a struct with that information and initialize it when you want to print that information. Perhaps something as trivial as this:
#include <stdio.h>
#include <string.h>
struct buildinfo {
int CONFIG_A;
int CONFIG_B;
};
void get_build_info(struct buildinfo *info)
{
if(info == NULL)
return;
memset(info, 0, sizeof *info);
#ifdef CONFIG_A
info->CONFIG_A = 1;
#endif
#ifdef CONFIG_B
info->CONFIG_B = 1;
#endif
}
int main(int argc, char **argv)
{
if(argc == 2 && strcmp(argv[1], "-v") == 0)
{
struct buildinfo info;
get_build_info(&info);
printf("build info: CONFIG_A: %s, CONFIG_B: %s\n",
info->CONFIG_A ? "yes" : "no",
info->CONFIG_B ? "yes" ; "no");
return 0;
}
...
return 0;
}
I you don't want to analyse the binary, then you can execute ./yourprogram -v and see the information printed on screen.
The best way will be to name the binary based upon the define used.
If you want to tell whether the binary was build with CONFIG_A or CONFIG_B just by inspection. On possible approach could be the following.
Put a signature depending on the configuration at a specific address (will work at any address too). e.g.
int main() {
#ifdef CONFIG_A
// this sign can be put at specific address with #pragma
const char sign[]="CONFIG_A";
init_config_a();
#elif defined(CONFIG_B) // only one shall be defined at a time
// this sign can be put at specific address with #pragma
const char sign[]="CONFIG_B";
init_config_b();
#endif
}
When you open the binary in a text editor you will be able to see the sign in ASCII view.

Implementing compile-time mechanism checking uniqueness of a string

The simplest way of defining my problem is that I'm trying to implement a mechanism that would check whether the same string had already been used (or a pair (number, string)). I would like this mechanism to be implemented in a smart way using C preprocessor. I would also like that this mechanism gave me compile errors when there is a conflict or run-time errors in Debug mode (by checking assertions). We don't want the developer to make a mistake when adding a message, as every message should be unique. I know that it could be done by calculating a hash or for example crc/md5 but this mechanism would be conflict-vulnerable which I need to avoid. It is crucial that every message can be used only once.
Example behaviour of this mechanism:
addMessage(1, "Message1") //OK
addMessage(2, "Message2") //OK
.
.
.
addMessage(N, "MessageN") //OK
addMessage(2, "Message2") //Compile error, Message2 has already been used
Alternative behaviour (when Debugging code):
addMessage(1, "Message1") //OK
addMessage(2, "Message2") //OK
.
.
.
addMessage(N, "MessageN") //OK
addMessage(2, "Message2") //Assertion failed, because Message2 has already been used
The preferred way of doing it would be smart usage of #define and #undef directives. In general the preprocessor should be used in a smart way (I am not sure if this is possible) maybe it can be achieved by appropriate combinations of macros? Any C preprocessor hacker that could help me solve this problem?
//EDIT: I need those messages to be unique globally, not only inside one code block (like function of if-statement).
//EDIT2: The best description of the problem would be that I have 100 different source files and I would like to check with a preprocessor (or possibly other mechanism other than parsing source files with a script at a start of the compilation every-time, which would be very time-consuming and would add another stage to an enough complicated project) if a string (or a preprocessor definition) was used more than one time. I still have no idea how to do it (I know it may not be possible at all but I hope it actually is).
This will give an error on duplicate strings:
constexpr bool isequal(char const *one, char const *two) {
return (*one && *two) ? (*one == *two && isequal(one + 1, two + 1))
: (!*one && !*two);
}
constexpr bool isunique(const char *test, const char* const* list)
{
return *list == 0 || !isequal(test, *list) && isunique(test, list + 1);
}
constexpr int no_duplicates(const char* const* list, int idx)
{
return *list == 0 ? -1 : (isunique(*list, list + 1) ? no_duplicates(list + 1, idx + 1) : idx);
}
template <int V1, int V2> struct assert_equality
{
static const char not_equal_warning = V1 + V2 + 1000;
};
template <int V> struct assert_equality<V, V>
{
static const bool not_equal_warning = 0;
};
constexpr const char* l[] = {"aa", "bb", "aa", 0};
static_assert(assert_equality<no_duplicates(l, 0), -1>::not_equal_warning == 0, "duplicates found");
Output from g++:
g++ -std=c++11 unique.cpp
unique.cpp: In instantiation of ‘const char assert_equality<0, -1>::not_equal_warning’:
unique.cpp:29:57: required from here
unique.cpp:20:53: warning: overflow in implicit constant conversion [-Woverflow]
unique.cpp:29:1: error: static assertion failed: duplicates found
The first template parameter (in this case 0) to 'assert_equality' tells you the fist position of a duplicate string.
I am not sure that it is easily doable using the standard C++ preprocessor (I guess that it is not). You might use some other preprocessor (e.g. GPP)
You could make it the other way: generate some X-macro "header" file from some other source (using e.g. a tiny awk script, which would verify the unicity). Then customize your build (e.g. add some rules to your Makefile) to run that generating script to produce the header file.
Alternatively, if you insist that processing being done inside the compiler, and if your compiler is a recent GCC, consider customizing GCC with MELT (e.g. by adding appropriate builtins or pragmas doing the job).
In the previous century, I hacked a small Emacs function to do a similar job (uniquely numbering error messages) within the emacs editor (renumbering some #define-s before saving the C file).
I am going to assume that something like this will work:
addMessage(1, "Message1")
addMessage(2, "Message1")
Or:
addMessage(1, "Message") /* transforms into "Message_1" */
addMessage(2, "Message_1") /* transforms into "Message_1_2" */
Because the C preprocessor expands tokens lazily and prohibits defining a macro from within another macro, it is impossible to save the results of executing one macro so that another macro can make use of it.
On the other hand, it is definitely possible to force uniqueness of symbols:
#define addMessage(N, MSG) const char *_error_message_##N (void) { return MSG; }
Or:
#define addMessage(N, MSG) const char *_error_message_##N (void) { return MSG "_" #N; }
Because during the link step, duplicate symbols with the name _error_message_NUMBER will trigger an error. And because it is a function, it cannot be used inside of another function without triggering an error.
Assuming your compiler is still not C++11 compliant as you have not tagged appropiately. I am also assuming that you are not particular about the Error Message, its just that you want it to work. In which case, the following Macro Based Solution might work for you
#include <iostream>
#include <string>
#define ADD_MESSAGE(N, MSG) \
char * MSG; \
addMessage(N, #MSG);
void addMessage(int n, std::string msg)
{
std::cout << msg << std::endl;
}
int main() {
ADD_MESSAGE(1, Message1); //OK
ADD_MESSAGE(2, Message2); //OK
ADD_MESSAGE(3, MessageN); //OK
ADD_MESSAGE(4, Message2); //Compile error, Message2 has already been used
};
Compile Output
prog.cpp: In function ‘int main()’:
prog.cpp:17:17: error: redeclaration of ‘char* Message2’
ADD_MESSAGE(4, Message2); //Compile error, Message2 has already been used
^
prog.cpp:4:8: note: in definition of macro ‘ADD_MESSAGE’
char * MSG; \
^
prog.cpp:15:17: error: ‘char* Message2’ previously declared here
ADD_MESSAGE(2, Message2); //OK
^
prog.cpp:4:8: note: in definition of macro ‘ADD_MESSAGE’
char * MSG; \
^
If you don't care about large amounts of useless boiler plate then here's one that's entirely the preprocessor, so no worries about scope, and then checks that they are unique at program startup.
In a file:
#ifndef ERROR1
#define ERROR1 "1"
#endif
#ifndef ERROR2
#define ERROR2 "2"
#endif
...
#ifndef ERROR255
#define ERROR255 "255"
#endif
#include <assert.h>
#include <set>
#include <string>
class CheckUnique {
CheckUnique() {
std::set<std::string> s;
static const char *messages = {
#if HAVE_BOOST
# include <boost/preprocessor.hpp>
# define BOOST_PP_LOCAL_LIMITS (1, 254)
# define BOOST_PP_LOCAL_MACRO(N) ERROR ## N,
# include BOOST_PP_LOCAL_ITERATE()
#else // HAVE_BOOST
ERROR1,
ERROR2,
...
#endif // HAVE_BOOST
ERROR255
};
for (int i = 0; i < sizeof messages / sizeof *messages; i++) {
if (s.count(messages[i]))
assert(! "I found two error messages that were the same");
else
s.insert(messages[i]);
}
}
};
static CheckUnique check;
This file can then be #included at the end of each source file, or you can place it into a file of its own and include every single file that has a #define ERROR line in it. That way, as soon as the operating system loads the program, the constructor for check will run and throw the exception.
This also requires you to have access to the Boost.Preprocessor library (and it's header only so it's pretty easy to set up). Although if you can't use that, then you can just hard code the error macros as I have shown with the #if HAVE_BOOST block.
Most of the boiler plate here is pretty simple, so if you generated it with a program (like some sort of portable script) then it would make your life far easier, but it can still be done all in one shot.

The inner working of #defines that call methods

I know that defines in the beginning of a C++ file are Preprocessor directives so "the preprocessor is executed before the actual compilation of code begins, therefore the preprocessor digests all these directives before any code is generated by the statements [1]".
Now what if I have this simple example:
#define PRINT(function) printFnctionName(#function)
void printFnctionName(string name)
{
cout << name;
}
void test(){};
int main(int argc, char *argv[])
{
PRINT(test);
}
So now my question is really how does the precompiler know what function will be passed in? and how is the pre-compilation/linking/compilation really happening?
Also, the reason I am using define and not a regular function, it is because I wasn't able to find a way to replicate this functionality `#function to retrieve the name of a function
So now my question is really how does the precompiler know what
function will be passed in? and how is the
pre-compilation/linking/compilation really happening?
Preprocessor doesn't know about anything. It simply replaces the text with the defined value and stringifies the value you passed in.
So the compiler sees it:
void printFnctionName(string name)
{
cout << name;
}
void test(){};
int main(int argc, char *argv[])
{
printFnctionName("test");
}
The preprocessor does text substitution. In your case, your code will be transformed to:
int main(int argc, char *argv[])
{
printFnctionName("test");
}
by the preprocessor before the rest of the compiling process kicks in. Some preprocessor directives are simple, other much more complicated (variable arity preprocessor directives, for instance).
Of course, it requires that you have included the correct header file etc.
For this particular case, there are two parts to the answer. One part is that C preprocessor knows nothing about what function is being called, it simply does the textual replacement.
The second part is the "stringifier", #function actually replaces test as an input to PRINT with "test". Of course, it doesn't have to be a function - just because it's called printfunction, you could do:
PRINT(a+b);
and you'd get the code:
printFnctionName("a+b");
or
PRINT(a-*&1,78^%j)
and get:
printFnctionName("a-*&1,78^%j");
[Why is the u missining in printFnctionName?]
The stringification operator is very useful if you have something like
#define ASSERT(x) do { if (!x) fail_assert(#x, __FILE__, __LINE__); } while(0)
void fail_assert(const char *expr, const char *file, int line)
{
cerr << "Assertion (" << expr << ") failed at " << file << ":" << line << endl;
}
....
ASSERT(ptr != NULL);
Now you get an error message "Assertion failed (ptr != NULL) at myprog.cpp:112", which can be quite useful.

how do I set a debug mode in c++

I would like to set a debug mode so that it prints the log statements only if the debug mode is on. For example if I have code like this
printf("something \n");
.
.
.
perror("something \n");
It only works if the debug flag is on.. I don't want to use "if" statements.
I think there is a clever way to do this using #define or something..
Thank is advance..
#ifdef _DEBUG // or #ifndef NDEBUG
#define LOG_MSG(...) printf(__VA_ARGS__) // Or simply LOG_MSG(msg) printf(msg)
#else
#define LOG_MSG(...) // Or LOG_MSG(msg)
#endif
On non-Debug built LOG_MSG would yeild to nothing. Instead of defining it with raw printf, you can have your custom logging-function, or class-method to be called.
Without going in to specific libraries or solutions, generally people make a logger class or function, and a single debug flag. The debug function checks this flag before calling printf or cout. Then in the rest of your code you simply call your debug function / method.
Here's an example:
class MyDebugger
{
private:
bool m_debug;
public:
MyDebugger();
void setDebug(bool debug);
void debug(const char* message);
};
MyDebugger::MyDebugger()
{
m_debug = false;
}
void MyDebugger::setDebug(bool debug)
{
m_debug = debug;
}
void MyDebugger::debug(const char* message)
{
if(m_debug)
{
cout << message << endl;
}
}
int main(int argc, char** argv)
{
MyDebugger debugger;
debugger.debug("This won't be shown");
debugger.setDebug(true);
debugger.debug("But this will");
return 0;
}
of course this is an incredibly naive implementation. In real logger classes there are many levels for finer-grained control of how much detail gets printed (levels like error, warning, info, and debug to differentiate the importance of the message). They might also let you log to files as well as stdout. Still this should give you a general idea.
In GCC, something like
#define debugprint(...) printf(__VA_ARGS__)
You can do a simple C-style macro definition (especially if you compiler is modern enough to do variable arguments macros, i.e. gcc or VS2005+) doing printf with a check of the debug level which can be a static global variable.
If you go with C++-style class similar to what #Chris suggests, I would make the logging function inline to ensure that when logging is disabled you are not wasting time on calling functions.