For the currently existing test framework I need to pass (during the first-most call) to the function a line number of a fragment inside of that function. Something like this:
#include <stdio.h>
void func(int line_num)
{
#define LINE_NUM (__LINE__ + 1)
if(line_num == __LINE__) // Check the passed arg against the current line.
printf("OK");
else
printf("FAIL");
}
int main(void)
{
func(LINE_NUM); // Pass to the func the line number inside of that func.
return 0;
}
(this is a minimalistic version of a more complex functionality).
As is the sample code prints "FAIL".
If I pass an absolute value 5, e.g. func(5) then it prints "OK". I don't like the absolute value 5 because if I add one more line in front of the func definition then the absolute value will need a correction.
Instead of #define LINE_NUM (__LINE__ + 1) I also tried the following:
1.
#define VALUE_OF(x) x
#define LINE_NUM (VALUE_OF(__LINE__) + 1)
2.
#define VAL(a,x) a##x
#define LOG_LINE() ( VAL( /*Nothing*/,__LINE__) + 1)
3.
#define VALUE_OF2(x) x
#define VALUE_OF(x) VALUE_OF2(x)
#define LINE_NUM (VALUE_OF(__LINE__) + 1)
I'm using:
gcc --version
gcc (Ubuntu/Linaro 4.6.3-1ubuntu5) 4.6.3
In my sample code the value that func() gets is 14 (the call site line number + 1).
You cannot get the preprocessor to expand __LINE__ in a macro definition. That's not the way the preprocessor works.
But you can create global constants.
#include <stdio.h>
static const int func_line_num = __LINE__ + 3;
void func(int line_num)
{
if(line_num == __LINE__) // Check the passed arg against the current line.
printf("OK");
else
printf("FAIL");
}
int main(void)
{
func(func_line_num); // Pass to the func the line number inside of that func.
return 0;
}
If you don't like static const int, for whatever reason, you could use an enum:
enum { FUNC_LINE_NUM = __LINE__ + 3 };
Unfortunately, whether you use a global constant or an enum, you have to put the definition at file scope, which might make it somewhat distant from the use point. However, it is not immediately apparent why the precise line number of the test needs to be used, rather than (for example) the first line of the function or even any integer guaranteed to be unique:
#include <stdio.h>
// As long as all uses of __LINE__ are on different lines, the
// resulting values will be different, at least within this file.
enum { FUNC_LINE_NUM = __LINE__ };
void func(int line_num)
{
if(line_num == FILE_LINE_NUM) // Check the passed arg against the appropriate constant.
printf("OK");
else
printf("FAIL");
}
int main(void)
{
func(func_line_num); // Pass to the func the line number inside of that func.
return 0;
}
After #rici 's great answer and comments the closest thing to what I need is the following:
#include <stdio.h>
#define LINE_NUM_TESTER() \
enum { LINE_NUM = __LINE__ }; \
\
void line_num_tester(int line_num) \
{ \
if(line_num == __LINE__) \
printf("OK\n"); \
else \
printf("FAIL. line_num: %d, __LINE__: %d.\n", line_num, __LINE__); \
}
LINE_NUM_TESTER()
int main(void)
{
line_num_tester(LINE_NUM);
return 0;
}
In C++, is there a methodology by means of the preprocessor to substitute for a variable name followed by an index number by: its name followed by '[' followed by the index number, followed by ']'?
As an example, if I write:
int main(void)
{
int var[64];
var0 = 0;
var1 = 1;
var2 = 2; // etc...
return 0;
}
Translation:
int main(void)
{
int var[64];
var[0] = 0;
var[1] = 1;
var[2] = 2; // etc...
return 0;
}
#define is going to be the closest you can get.
#define var0 var[0]
#define var1 var[1]
...
However, it should be noted if you're going to use the above, you may as well just do it manually in the first place, since you're typing everything out anyway.
No. Thanks to language creators! There is no way to make syntax analysis (string parsing) inside macro definition.
It would be the real hell to read such programs.
Recently I'm working on Macros and I got stuck in very simple problem. Here is my code:
#include <iostream>
#define abs(A) (A<0)? -A:A;
using namespace std;
int dis(int x, int y)
{
return abs(x-y);
}
int main()
{
cout<<dis(2,4);
}
Basically abs() takes the absolute of the given value, then the distance is calculated. But in this case it gives the output -6 rather than the 2.
This is because of the way your macro will be evaluated, i.e. during the preprocessor stage of code compilation process, the return abs(x-y) would be changed to:
return abs(x-y)
(A<0) -> -A
(2-4) < 0 = -2 -> -2-4 = -6
You should either change the definition of your macro (better solution), by wrapping macro variables in brackets, to:
#define abs(A) ((A)<0) ? -(A):(A);
or change your code to:
int dis(int x, int y)
{
int res = x-y;
return abs(res);
}
Please note that there is also a abs() function in C Standard Library.
First a little code:
int counter = 0;
int get_counter() { return counter++; }
#define EVEN_OR_ZERO(cc) ( (cc) % 2 == 0 ? (cc) : 0 )
int next_even_or_zero = EVEN_OR_ZERO(get_counter());
This code might seem OK, but... Let's expand the macro:
int next_even_or_zero = get_counter() % 2 == 0 ? get_counter() : 0;
As you can see the macro will only return odd numbers - which is the opposite of what was expected (or desired).
The question: Is there any way to get this work as intended with a macro? Or is a regular function the only way to go?
//This works as wanted
int even_or_zero(int value) { return value % 2 == 0 ? value : 0; }
#define EVEN_OR_ZERO(cc) even_or_zero(cc)
This may be the perfect answer or a bad joke, depending on why you need a macro, which you haven't told us.
The answer is simple: Don't use a macro, unless there's a good reason for it. This case isn't one of them:
int even_or_zero(int i) {
if (i % 2) {
return 0;
} else {
return i;
}
}
Make two functions.
int getCurrentCounter() { ... } // just return here
int getNextCounter() { ... } // increment here
This is how - in example - sequences is PSQL works.
Also, this seems like very bad code design.
don't use macros in C++, there are more better ways to achieve what you want (usally) without using them
functions with sideeffects on global variables are not that good. Think if it would not be better to create struct/class with it's counter and add methods to it. Or better yet, could hide methods as prive at set methods/class as their friends to limit who can affect counter.
Is there a way to add or edit the message thrown by assert? I'd like to use something like
assert(a == b, "A must be equal to B");
Then, the compiler adds line, time and so on...
Is it possible?
A hack I've seen around is to use the && operator. Since a pointer "is true" if it's non-null, you can do the following without altering the condition:
assert(a == b && "A is not equal to B");
Since assert shows the condition that failed, it will display your message too. If it's not enough, you can write your own myAssert function or macro that will display whatever you want.
Another option is to reverse the operands and use the comma operator. You need extra parentheses so the comma isn't treated as a delimiter between the arguments:
assert(("A must be equal to B", a == b));
(this was copied from above comments, for better visibility)
Here's my version of assert macro, which accepts the message and prints everything out in a clear way:
#include <iostream>
#ifndef NDEBUG
# define M_Assert(Expr, Msg) \
__M_Assert(#Expr, Expr, __FILE__, __LINE__, Msg)
#else
# define M_Assert(Expr, Msg) ;
#endif
void __M_Assert(const char* expr_str, bool expr, const char* file, int line, const char* msg)
{
if (!expr)
{
std::cerr << "Assert failed:\t" << msg << "\n"
<< "Expected:\t" << expr_str << "\n"
<< "Source:\t\t" << file << ", line " << line << "\n";
abort();
}
}
Now, you can use this
M_Assert(ptr != nullptr, "MyFunction: requires non-null argument");
And in case of failure you will get a message like this:
Assert failed: MyFunction: requires non-null argument
Expected: ptr != nullptr
Source: C:\MyProject\src.cpp, line 22
Nice and clean, feel free to use it in your code =)
BOOST_ASSERT_MSG(expre, msg)
http://www.boost.org/doc/libs/1_51_0/libs/utility/assert.html
You could either use that directly or copy Boost's code. Also note Boost assert is header only, so you could just grab that single file if you didn't want to install all of Boost.
As zneak's answer convolutes the code somewhat, a better approach is to merely comment the string text you're talking about. ie.:
assert(a == b); // A must be equal to B
Since the reader of the assert error will look up the file and line anyway from the error message, they will see the full explanation here.
Because, at the end of the day, this:
assert(number_of_frames != 0); // Has frames to update
reads better than this:
assert(number_of_frames != 0 && "Has frames to update");
in terms of human parsing of code ie. readability. Also not a language hack.
assert is a macro/function combination. you can define your own macro/function, using __FILE__, __BASE_FILE__, __LINE__ etc, with your own function that takes a custom message
If the assert is done within a class, an alternative approach is to call a static predicate function with a self-describing name. If the assertion fails, the message will already contain the predicate's pretty and self-describing name.
E.g.:
static bool arguments_must_be_ordered(int a, int b) {return a <= b;}
void foo(int a, int b)
{
assert(arguments_must_be_ordered(a, b));
// ...
}
You may even want to make that predicate function public so that the class' user can verify the precondition themselves.
Even if assert is not disabled for release builds, the compiler will likely inline the predicate if it's fairly trivial.
The same approach can be used for complex if conditions needing a comment. Instead of a comment, just call a self-describing predicate function.
You could also just write your own custom assert function. A very simple example:
bool print_if_false(const bool assertion, const char* msg) {
if(!assertion) {
// endl to flush
std::cout << msg << std::endl;
}
return assertion;
}
int main()
{
int i = 0;
int j = 1;
assert(print_if_false(i == j, "i and j should be equal"));
return 0;
}
play with the code.
The assertion reads Assertion print_if_false(i == j, "i and j should be equal").
int x=10, y=25;
assert(x > y); // Add message along with this assert
Option 1) Since fprintf returns number of characters printed so we can or assert expression with !fprintf. Using stderr here since this is an error message
assert((x > y) || !fprintf(stderr, "Error: x %d is expected to be greater than y %d \n", x, y));
We can wrap this inside a macro for convinient use.
// Define macro over assert
#define assert_msg(cond, fmt, ...) assert( cond || !fprintf(stderr, fmt, ##__VA_ARGS__))
// Use above macro
assert_msg(x > y, "Error: x %d is expected to be greater than y %d \n", x, y);
Option 2) Define error message wrapped inside lambda.
auto err = [x, y] { fprintf(stderr, "Error: x %d should be greater than y %d \n", x, y); return false; };
assert((x > y) || err()); // Assert calls lambda func only when condition fails
Here is the dumped message.
Error: x 10 should be greater than y 25
File.cpp:10: int main(): Assertion `(x > y) || err()' failed.
Option 3) Or we can refine above solution to do it in one line with help of immediately invoked lambda
assert((x > y) || ([x, y] { fprintf(stderr, "Error: x %d is expected to be greater than y %d \n", x, y); return false; }()));
For vc, add following code in assert.h,
#define assert2(_Expression, _Msg) (void)( (!!(_Expression)) || (_wassert(_CRT_WIDE(#_Msg), _CRT_WIDE(__FILE__), __LINE__), 0) )