Macro that inserts code into control structure - c++

I have a waitUntil macro defined as
#define waitUntil(condition) while(!(condition)) delay(10);
Occasionally, I need code like updating a variable in that while loop. Given the definition of the macro, it is not usable, and I have to revert back to writing the while-loop and delay.
while(!condition){
counter++;
delay(10);
}
Is there a way to re-write the macro to allow code in the loop body?
A better example is #define FOR(count) for(int i = 0; i < count; i++)
This is ok, because
FOR(5){
//body
}
expands into
for(int i = 0; i < 5; i++){
//body
}
I can't do this with the while loop since that delay must be present.
EDIT:
Thank you for the answers. Yes, I understand the preference for functions over macros in C++. Also, I get the standard for all-caps, but this is a very small codebase, and only 4 of us will really interact with it and we all know waitUntil is a macro.
While passing a function to it would work, I was looking for a way that didn't need the code to be passed into the macro. If that is the only option, it's ok; then a direct while loop is probably best.
Something that should do what I want is:
#define waitUntil(condition) while(!(condition)){ delay(10);
Which should then be able to be used as
waitUntil(counter > 4)
counter++;
}
But this has clear issues.

You don't really need a macro for this. Here is a function template implementation:
template<typename C, typename F>
void waitUntilAndDo(C condition, F func) {
while(!condition()) {
func();
delay(10);
}
}
which can be called, e.g. as
waitUntilAndDo([&]{ return counter < 100; }, [&]{ counter++; });
You can also just do this with a single function argument of course:
template<typename C>
void waitUntil(C condition) {
while(!condition()) {
delay(10);
}
}
called as e.g.
waitUntil([&]{
/* something to do */
return /* condition */;
});
with the caveat that this executes /* something to do */ even if the loop condition is false from the beginning (which could of course also be resolved in the condition lambda, but wouldn't look nice).
Although just writing out the loop is probably clearer in any case.

If you specifically want a macro that uses a while loop internally and can still execute arbitrary code followed by a delay then you need to put the delay into the while loop condition:
#define waitUntil(condition) while(delay(10),!(condition))
The comma operator make delay(10) execute first, followed by !(condition) (left to right executrion) - the last expression determines the result of the whole expression.
You can try it here: https://www.onlinegdb.com/uQqle2qxo
The downside is that delay(10) is executed at least once - even if the condition is already met. If you use a for loop the condition can be checked before the loop executes and the delay can happen after the arbitrary code:
#define waitUntil(condition) for(;!(condition);delay(10))
You can try it here: https://www.onlinegdb.com/LeK3OPv9Y

Related

Macro for while loop with deferred function call

I would like to construct a macro where a predefined function (here simulated by "call fcn here") is called every time when the loop ends an iteration. This is what I have so far, which actually works.
Is there shorter way, eventually with more macro magic to write such behavior?
#define MYWHILE(condition) \
while( \
[]()->bool { \
static bool called = false; \
if(called) std::cout<<"call fcn here"<<std::endl; \
called=true; return true;}() \
&& condition)
This macro should than be used on several places in the code to ensure than nobody forgets to call the function when they write busy waiting loops.
A typical example would be:
while(true){
bool b = foo();
if(b){
break;
}
ros::spinOnce();
}
Where oft the call ros::spinOnce() is forgotten, so I simply replace the sample code with:
MYWHILE(true){
bool b = foo();
if(b){
break;
}
}
Pure C - Code would also be fine.
Rather than a complicated looking while loop, you can package up what you need into a for loop:
for (; condition; fcn())
The function will be called at the end of every iteration, before reevaluating the condition.
I would like to construct a macro where a predefined function (here
simulated by "call fcn here") is called every time when the loop ends
an iteration, but NOT at the first time.
Since your provided code and your question conflict, it is not clear what behavior you want. To implement the above, I would recommend not using macros at all and simply writing your code as:
do {
if(!condition)
break;
// More code here
} while(fcn());
What's wrong with just:
while(!foo()) {
ros::spinOnce();
}
That is logically equivalent to:
while(true){
bool b = foo();
if(b){
break;
}
ros::spinOnce();
}
Yet far simpler than:
MYWHILE(true){
bool b = foo();
if(b){
break;
}
}

Put the condition of using an"if" in preprocessor C++

I wrote a code in cpp. I have a loop in my code which have to execute in specified frequency.
I want whenever the choosen frequency equal or more than 70hz an "if" statement to work, and whenever not the content of if executes without "if", but I don't know how to write it in as preprocessor. I wrote something like this but it always executes "else" part of this:
#define Freq70Hz 70
int frequency = Freq70Hz;
int main
{
while(true)
{
#if frequency == Freq70Hz
if(condition ){
// do the firstthing
}
#else
// do the firstthing
#endif
}
}
Here you are mixing static, compile time programming with dynamic, run time programming. In this case, how would the preprocessor know the value of frequency at compile-time? It could change during the execution of the program. You either want to have a static solution like this:
#define FREQUENCY 70 //this can be changed by passing in compiler options
int main()
{
while(true)
{
#if FREQUENCY > 70
if(condition ){
// do the firstthing
}
#else
// do the firstthing
#endif
}
}
Or you want a dynamic solution like this:
int frequency = 70;
int main()
{
while(true)
{
if(frequency == 70 && condition)
{
// do the firstthing
}
else
{
// do the firstthing
}
}
}
You are misunderstanding what the preprocessor does.
The preprocessor does text processing, before the program runs.
In particular, it sees normal variables only as text and has no idea what their types are or values will be at run time. That's true even if they are global variables like your frequency which is initialized when the program starts. We see that; the preprocessor doesn't.
What looks like an alias definition in #define Freq70Hz 70 is just a text replacement rule for the remaining part of the file. The text ("Freq70Hz") will be replaced (by "70") whenever it appears in the rest of the program -- but before the compiler sees the code.
Then you fall victim to a quirk of the preprocessor spec.
You think that the line #if frequency == Freq70Hz is meaningfully evaluated. You hope that the value of the variable frequency, which we (but not the preprocessor!) know to be 70, will be taken into account. But that's not what happens.
The preprocessor sees the preprocessor token frequency. It has no notion of frequency being an int variable, because it cannot understand the C programming language. It sees that this token is part of a conditional preprocessor expression. It has not been told to replace it with a value though.
Now the catch: Identifiers which are still there after all replacements have been performed in a preprocessor conditional expression are replaced with 0 (!), cf. latest C draft n1570, 6.10.1./4. The preprocessor does not complain about "undefined identifiers". This makes the directive #if frequency == Freq70Hz #if 0 == 70, which obviously is always false.
Since this default use of undefined preprocessor identifiers is a dangerous feature -- normal programming languages stopped doing that after Basic --, it's worth knowing a trick somebody showed me long ago: Use macro functions. #define Freq70Hz() 70 will be functionally equivalent but complain when you misspell it later.
Using dead code elimination with templates
template<bool isGE70Hz>
void DoWhile() {
while(true) {
if (isGE70Hz) { // dead code elimination as isGE70Hz is compiletime constant.
if(condition ){
// do the firstthing
}
} else {
// do the firstthing
}
}
}
int main() {
if (frequency >= Freq70Hz) // chose specialization
DoWhile<true>()
else
DoWhile<false>()
// if frequency and Freq70Hz both are compiletime constants you could do
// DoWhile<frequency >= Freq70Hz>
}
Assuming // do the firstthing is the SAME in both and assuming frequency is supposed to not change in your execution, I wouldn't use the pre-processor for this... if you use static const int frequency = Freq70Hz then later do:
while(true)
{
if(condition || frequency == Freq70Hz){
// do the firstthing
}
}
The compiler will compile out the appropriate thing based on the knowledge that frequency won't change. That is, if frequency == Freq70Hz then the whole if part won't be in a release executable. If frequency != Freq70Hz then the if part will just be the condition.

C/C++ optimizing away checks to see if a function has already been run before

Let's say you have a function in C/C++, that behaves a certain way the first time it runs. And then, all other times it behaves another way (see below for example). After it runs the first time, the if statement becomes redundant and could be optimized away if speed is important. Is there any way to make this optimization?
bool val = true;
void function1() {
if (val == true) {
// do something
val = false;
}
else {
// do other stuff, val is never set to true again
}
}
gcc has a builtin function that let you inform the implementation about branch prediction:
__builtin_expect
http://gcc.gnu.org/onlinedocs/gcc/Other-Builtins.html
For example in your case:
bool val = true;
void function1()
{
if (__builtin_expect(val, 0)) {
// do something
val = false;
}
else {
// do other stuff, val is never set to true again
}
}
You should only make the change if you're certain that it truly is a bottleneck. With branch-prediction, the if statement is probably instant, since it's a very predictable pattern.
That said, you can use callbacks:
#include <iostream>
using namespace std;
typedef void (*FunPtr) (void);
FunPtr method;
void subsequentRun()
{
std::cout << "subsequent call" << std::endl;
}
void firstRun()
{
std::cout << "first run" << std::endl;
method = subsequentRun;
}
int main()
{
method = firstRun;
method();
method();
method();
}
produces the output:
first run subsequent call subsequent call
You could use a function pointer but then it will require an indirect call in any case:
void (*yourFunction)(void) = &firstCall;
void firstCall() {
..
yourFunction = &otherCalls;
}
void otherCalls() {
..
}
void main()
{
yourFunction();
}
One possible method is to compile two different versions of the function (this can be done from a single function in the source with templates), and use a function pointer or object to decide at runtime. However, the pointer overhead will likely outweigh any potential gains unless your function is really expensive.
You could use a static member variable instead of a global variable..
Or, if the code you're running the first time changes something for all future uses (eg, opening a file?), you could use that change as a check to determine whether or not to run the code (ie, check if the file is open). This would save you the extra variable. Also, it might help with error checking - if for some reason the initial change is be unchanged by another operation (eg, the file is on removable media that is removed improperly), your check could try to re-do the change.
A compiler can only optimize what is known at compile time.
In your case, the value of val is only known at runtime, so it can't be optimized.
The if test is very quick, you shouldn't worry about optimizing it.
If you'd like to make the code a little bit cleaner you could make the variable local to the function using static:
void function() {
static bool firstRun = true;
if (firstRun) {
firstRun = false;
...
}
else {
...
}
}
On entering the function for the first time, firstRun would be true, and it would persist so each time the function is called, the firstRun variable will be the same instance as the ones before it (and will be false each subsequent time).
This could be used well with #ouah's solution.
Compilers like g++ (and I'm sure msvc) support generating profile data upon a first run, then using that data to better guess what branches are most likely to be followed, and optimizing accordingly. If you're using gcc, look at the -fprofile-generate option.
The expected behavior is that the compiler will optimize that if statement such that the else will be ordered first, thus avoiding the jmp operation on all your subsequent calls, making it pretty much as fast as if it wern't there, especially if you return somewhere in that else (thus avoiding having to jump past the 'if' statements)
One way to make this optimization is to split the function in two. Instead of:
void function1()
{
if (val == true) {
// do something
val = false;
} else {
// do other stuff
}
}
Do this:
void function1()
{
// do something
}
void function2()
{
// do other stuff
}
One thing you can do is put the logic into the constructor of an object, which is then defined static. If such a static object occurs in a block scope, the constructor is run the fist time that an execution of that scope takes place. The once-only check is emitted by the compiler.
You can also put static objects at file scope, and then they are initialized before main is called.
I'm giving this answer because perhaps you're not making effective use of C++ classes.
(Regarding C/C++, there is no such language. There is C and there is C++. Are you working in C that has to also compile as C++ (sometimes called, unofficially, "Clean C"), or are you really working in C++?)
What is "Clean C" and how does it differ from standard C?
To remain compiler INDEPENDENT you can code the parts of if() in one function and else{} in another. almost all compilers optimize the if() else{} - so, once the most LIKELY being the else{} - hence code the occasional executable code in if() and the rest in a separate function that's called in else

C++ SDL Breaking out of while loop

I've been messing around with C++ SDL for a few days now and I've come across an interesting problem.
SDL_Event event1;
while(SDL_WaitEvent(&event1))
{
for(size_t i = 0; i < MainMenuOptions.size();i++)
{
if(event1.button.x > MainMenuOptions.at(i).GetX() && event1.button.x < (MainMenuOptions.at(i).GetX() + MainMenuOptions.at(i).GetWidth())
&& event1.button.y > MainMenuOptions.at(i).GetY() && event1.button.y < (MainMenuOptions.at(i).GetY() + MainMenuOptions.at(i).GetHeight()))
{
break;
}
}
}
When I use break in the for loop its going to break out of the for loop instead of the while loop. How would I break out the while loop instead without using the goto statement? (the goto statement is bad programming, I heard)
The common solution is to put this stuff into its own function and return from that:
inline SDL_Event do_it()
{
SDL_Event event;
while(SDL_WaitEvent(&event))
for(std::size_t i = 0; i < MainMenuOptions.size(); ++i)
if(/*...*/)
return event;
return event; // or whatever else suits, I know too little about your code
}
There's another answer to that, and I think I should say it before everyone will downvote me.
Using a variable is certainly a "good" way to do it. However, the creating additional variable just to jump out of the loop seems a bit of overkill, right?
So yes, this time goto is perfect solution. It's perfectly clear what you are doing with it, you are not using another variable and the code remains short, maintainable and readable.
The statement goto is bad practice is mostly a remnant of the BASIC times, when it was quite the only way of changing code flow. However, now we "know better", and saying that the goto or any other construction is bad, just doesn't cut it. It can be bad for one particular problem you are trying to solve with it (and it's the case with most of the problems that people try to solve with goto). However, given the right circumstances (like here) it's OK. I don't want to start a debate here, of course. Goto is like a very powerful tool (sledgehammer, for example). It has its uses and you can't say a tool is totally bad; it's the user using it in the wrong way.
Use a variable to indicate the need to exit:
bool exit_program = false;
while( !exit_program && SDL_WaitEvent(&event1) )
{
for( /* ... */ )
{
exit_program = true;
}
}
First point: IMO, you're trying to wrap too much up into a single place, and ending up with something that's fairly difficult to understand -- somebody has to read through that entire long set of comparisons before they can understand any of what this is supposed to accomplish at all.
Second point: using an explicit loop to iterate over a standard collection is usually a mistake -- and this is no exception. The standard library already has an algorithm to accomplish the same basic thing as your loop. It's better to use that than write it again yourself.
template <class T>
bool in_range(T a, T b, T c) {
return (a > b) && (a < b+c);
}
class in_rect {
point p;
public:
in_rect(point const &p) : p(p) {}
// Not sure of the type of objects in MainMenuOptions, so just T for now.
//
bool operator()(T const &m) {
return in_range(p.x, m.GetX(), m.GetWidth())
&& in_range(p.y, m.GetY(), m.GetHeight());
}
};
SDL_Event event1;
while (SDL_WaitEvent(&event1))
if (std::any_of(MainMenuOptions.begin(), MainMenuOptions.end(),
in_rect(event1.button))
break;
Once we fix the other problems, there's simply no longer any need (or even use) for the goto. We haven't taken any steps explicitly intended to remove it, but when the other problems have been fixed (especially, replacing the loop with an appropriate algorithm), the use for it has disappeared.
I suppose I should preemptively comment on the increase in the total number of lines of code: yes, there are more lines of code. What of it? If we really wanted to, we could use the same basic approach, but instead of defining in_rect and in_range, we'd basically just take the condition from the original if statement and stuff it into a lambda. While I'm very happy that lambdas have been added to C++, in this case I'm not excited about using it. It would get rid of the goto, but in general the code would be almost as unreadable as it started out.
Simply put, the number of lines isn't a good way to measure much of anything.
A solution without additional variable and goto:
while(SDL_WaitEvent(&event1))
{
size_t i;
for(i = 0; i < MainMenuOptions.size();i++)
{
if(/* ... */)
{
break;
}
}
if (i < MainMenuOptions.size())
break;
}

Style question about existing piece of code (C/C++)

I just hope the following doesn't seem to you like redundant jabber :)
Anyway, there is that:
for (p = fmt; *p; p++) {
if (*p != '%') {
putchar(*p);
continue;
}
switch (*++p) {
/* Some cases here */
...
}
}
And I wondered why the writer (Kernighan / Ritchie) used the continue in the if statement.
I thought it was for the mere reason that he deemed it would be more elegant than indenting the whole switch under an else statement, what do you think?
Probably. The human brain has limited stack space, making it difficult to deal with deeply nested structures. Anything that flattens the information we're expected to parse makes it easier to understand.
Similarly, I normally prefer this:
bool foo(int arg)
{
if(!arg) {
/* arg can't be 0 */
return false;
}
/* Do some work */
return true;
}
To this:
bool foo(int arg)
{
if(!arg) {
/* arg can't be 0 */
return false;
} else {
/* Do some work */
return true;
}
}
Or worse, to this:
bool foo(int arg)
{
if(arg) {
/* Do some work */
return true;
} else {
/* arg can't be 0 */
return false;
}
}
In the last example, the part that does the work might be quite long. By the time the reader gets to the else clause, he may not remember how he got there.
Putting the bail out conditions as close to the beginning helps to assure that people who try to call your functions will have a good idea of what inputs the function expects.
Also, as others pointed out, the continue makes it clear that there's no need to read further into the code inside the loop to determine whether any more processing is done after that point for this case, making the code easier to follow. Again, the fewer things you force the reader to keep track of, the better.
Because with the continue it is clear that the code is done for this loop iteration. If a else would have been used you had also to check if there is no code after the else.
I think it is general a good habit to exit a context as soon as possible because this leads to much clearer code.
For example:
if(arg1 == NULL)
return;
if(arg2 == NULL)
return;
//Do some stuff
vs.
if(arg1 != null)
{
if(arg2 != null)
{
//Do some stuff
}
}
It is just so much easier to read when it's put like this.
Are we done here with this iteration through the loop? Yes? So let us continue with the next iteration.
I think that he would have reasons enough to indent the code under the switch, and indenting the entire meat of the function is quite wasteful of horizontal space. At the time the code was written, I imagine 80 character widths were still popular.
I don't think it is difficult to understand, but I do think that it's quite nice to mention what you DON'T do immediately, and then GTFO.
There are always many ways to write code like this -
Putting the entire switch inside an else statement would be perfectly valid. I suppose the reason they did it this way ~may~ have been just the way they were thinking at the time:
"if the value at p does not equal '%', put then continue on."
If you have switch under an else, it may not have been as obvious to the writer that you were jumping to the next iteration in that specific case.
This is completely personal style choices, though. I wouldn't worry too much - just write it in a way that makes the most sense to you and your team.
I agree.
But you can't look at it as a "mere reason", it's actually a pretty good reason, because it reduces the over all complexity of the code. Making it shorter and easier to read and understand.
If you use an else then everything inside the else needs to be indented:
if ()
{
doA();
}
else
{
doB();
if ()
{
doC();
}
else
{
doD()
}
}
If you use continue then you don't need to indent:
if ()
{
doA()
continue;
}
doB();
if ()
{
doC();
continue;
}
doD();
Also, continue means that I can stop thinking about that case: for example, if I see else then perhaps there'll be more processing of the '%' case later in the loop, i.e. at the end of the else statement; whereas on seeing continue I know instantly that the processing of the '%' case in the loop is completely finished.
The most probable reason is that the switch that follows is rather long - this looks like printf format parsing.
There could be more that one reason to continue/break a loop. So it would look next:
loop
{
if (cond1)
{
if (cond2)
{
if (cond2)
{
more conditions...
}
}
}
else
{
the loop action
}
}
IMHO it's not so elegant and readable as the loop in your example, e.g:
loop
{
if (cond1)
continue;
if (cond2)
continue;
if (cond2)
continue;
if( more conditions...)
continue;
the loop action
}
And you don't even need to understand all structure of all "if"s (it could be much more complex) to understand the loop logic.
P.S. just for the case: I don't think the authors thought about how to write this loop, they just wrote it:)
I stick to Dijkstra's teachings: goto is harmful. And continue/break are goto's little brothers.
If the problem is that you're indenting the code too much, the solution is not putting a continue in the loop, but reducing the complexity by separating the code in different functions or thinking about a better way of organizing it.
For example, #Kamarey snippet would be even clearer like this:
loop
{
if (!(cond1 ||
cond2 ||
cond2 ||
...))
{
the loop actions;
}
}
or #Ori Pessach example could be expressed like:
bool foo(int arg)
{
if(arg) {
/*do some work*/
}
return arg != 0;
}
In brief, usually I can't find a good enough reason to use non structured programming constructs (maybe for some cleanup codes in a very limited ocasions...)
Well, I wrote C programs for about 11 years and I had to read 5 times your piece of code to understand it !
Kernighan and Ritchie were active in the sixties. At that time, being able to understand a piece of code was not relevant. Being able to write code that fit in 16 Ko was.
So I'm not suprised. C is a terrible language when your teatchers are K & R. Just look at realloc : who would know code something like that today ? In the '60ies, it was all the rage, but it is now appalling, at least :o)