I wan't something like:
#define some_func(a) some_func(a, create_foo())
and then when using:
void loop() {
some_func(3);
some_func(40);
}
the Foo instance should only be created once for each line.
So in the above case, 2 times. And when loop is running again, it should not create the Foo instances again.
Is such a thing possible?
Here is the complete non working program:
The output should be 3, 40, 6, 80, 9, 120, 12, 160, ...
typedef struct {
int a;
} Foo;
Foo create_foo() {
return {0};
}
void some_func(int a, Foo &f) {
f.a += a;
Serial.println(f.a);
}
#define some_func(a) some_func(a, create_foo())
void setup() {
Serial.begin(9600);
}
void loop() {
some_func(3); // 3, 6, 9, 12
some_func(40); // 40, 80, 120, 160
}
Edit.
I tried to isolate the example to a bare minimum, but i'm shooting myself in the foot now. In the actual thing, I don't have a void as return type but a boolean.
So I try something like this now:
#define debounce(val) for(static auto d = create_debounce(); debounce(d, val), false;)
But that of course fails when used with:
int state = debounce(digitalRead(BUTTON_FIRE));
Cause the macro is not giving a value back so no assignment can happen.
So I need something like:
#define debounce(val) true; for(static auto d = create_debounce(); debounce(d, val), false;)
where true is the result of the create_debounce function.
So can poison it even more to make it possible? Here is the complete code:
// ----------------- L I B R A R Y . S T U F F -------------------------
#define debounce_delay 50
typedef struct {
int state;
int last_state;
unsigned long last_state_change_time;
} Debounce;
Debounce create_debounce() {
return {0, 0, 0L};
}
boolean debounce(Debounce &deb, int val) {
if (val != deb.last_state) {
deb.last_state_change_time = millis();
deb.last_state = val;
}
else if ((millis() - deb.last_state_change_time) > debounce_delay) {
deb.state = val;
}
return deb.state;
}
//#define debounce(val) for(static auto d = create_debounce(); debounce(d, val), false;)
#define debounce(val) true; for(static auto d = create_debounce(); debounce(d, val), false;)
// ----------------- S K E T C H -------------------------
#define BUTTON_FIRE 7
void setup() {
Serial.begin(9600);
}
void loop() {
int state = debounce(digitalRead(BUTTON_FIRE));
if (state == HIGH) {
Serial.println("HIGH");
}
else {
Serial.println("LOW");
}
}
If you are willing to get really ugly, you can accomplish practically anything. I'm only answering this because this is a brain teaser.
You can define the macro like this:
#define some_func(a) for(static auto f = create_foo(); some_func(a, f), false;)
Yes, this will work. In standard C++, the init clause of a for loop can contain a static variable declaration. So the variable will be initialized only once. Then the "condition" is the actual call to some_func followed by the comma operator with false, so the function is only execute once each time the for loop is entered.
Adapting your code from Arduino to standard C++, and simulating the four cycles, generated the same output you wanted. See it live.
Alternatively, if you want to appear slightly less cryptic (but why would you?), you can opt for this:
#define some_func(a) do {static auto f = create_foo(); some_func(a, f); } while(0)
Same thing really.
Alright, applying it to your actual problem calls for something different:
#define debounce(a) [](int v){static Debounce d = create_debounce(); \
return debounce(d, v); }(a)
This defines and immediately invokes a lambda. Since a lambda creates a unique closure type everywhere it appears in a program, this will create a unique static object for every expression you write debounce(...) in. An alternative is the GCC specific statement expression. But unlike a lambda, that is an extension. Which you may or may not want to use, YMMV.
When the loop is run again, then the Foo instances are created again, they are not restore from the previous run.
I suspect what you want to do is using a set of static variables. Or refactor your code for clarity.
This macro is not helping you in this matter, don't use it, use explicit variables and then you will see the lifetime of objects. A macro is not part of the compiler, but of the preprocessor.
Besides being ill-formed, your macro isn't useful for what you want because you're calling create_foo on each invocation.
You can use static variables:
void loop() {
static Foo f1, f2;
some_func(3, f1);
some_func(40, f2);
}
The first thing to note, is that your state is a boolean. This will save you a few bytes of RAM.
The next thing to point out is that you want to ignore changes to the input for a period of time; this means you don't need to store the "current" state; just the last state... which will end up being the same. This might not save you anything, since the 2 booleans and 1 boolean will likely just take a byte; but it gives the compiler a chance, and most importantly, makes things simpler.
With those 2 fairly minor improvements made, we get to the bigger ones. Don't use macros unless you really know what you're doing; and even then reconsider.
Arduino example code tends to offer them because someone thought it would make it easier to learn; but honestly, they don't. They're not a function, and your usage of it really isn't doing what you think it's doing. Arduino offer limited ways to debug it, so you can't actually tell that your state will ALWAYS be high, because the macro expansion is this:
int state = true;
for(static auto d = create_debounce();
debounce(d, val),
false;);
//New lines added for clarity.
Move it to a function; let the compiler optimise the code because it will ALWAYS do a better job than you as long as you write the code in a way that lets it.
Related
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 4 years ago.
Improve this question
Question: is it OK to rely on compiler optimizations while coding?
Let's say I need to calculate calculateF and calcuateG which both depend on another value returned by getValue. Sometimes I need both values, some other times I only need one of those values.
// some function
double getValue(double value)
{
double val(0.0);
// do some math with value
return val;
}
// calculateF depends on getValue
double calculateF(double value)
{
double f(0.0);
auto val = getValue(value);
// calculate f which depends on val (and value)
return f;
}
// calculateG depends on getValue
double calculateG(double value)
{
double g(0.0);
auto val = getValue(value);
// calculate g which depends on val (and value)
return g;
}
Now, I could write this more elegantly:
std::pair<double,double> calculateFG(double value)
{
auto val = getValue(value);
double f(0.0), g(0.0);
// calculate f and g which depend on val (and value)
return {f,g};
}
If I want both values:
double value(5.3);
auto [f,g] = calculateFG(value); // since C++17
// do things with f and g
If I want only 1 value, say f, I just don't use g and it will be optimized out. So, the performance of calculateFG is exactly the same as calculateF if I don't use g. Furthermore, if I need both f and g, I only need to call getValue once instead of twice.
The code is cleaner (only 1 function calculateFG instead of calculateF and calculateG), and faster if both f and g are required. But is relying on the compiler optimization a wise choice?
It is hard to say if it is wise or not. It depends on compiler optimization - function inlining.
If calculateFG is inlined, the complier can optimize out the unused one. Once inlined, g is unused so all the code for generating g is dead code[1]. (It may not be able, for example, if the calculation code has some side effects)
If not, I don't think the optimization can be applied(Always calc f and g).
Now you may wonder if it is possible to always inline specific functions.
Please note that giving inline keyword does not force the compiler to inline that function. It is just a hint. With or without the keyword, it is the compiler's call. It seems like there is non-standard way though - How do I force gcc to inline a function?
[1]Relavent compiler options : -fdce -fdse -ftree-dce -ftree-dse
Modern C++ compilers are pretty good at optimization choices, given the chance.
That is to say, if you declare a function inline, that does not mean the optimizer will actually ilnine it 100% of the time. The effect is more subtle: inline means you avoid the One Definition Rule, so the function definition can go into header files. That makes it a lot easier for the optimizer.
Now with your examples of double [f,g], optimizers are very good at tracking the use of simple scalar values, and will be able to eliminate write-only operations. Inlining allows the optimizer to eliminate unnecessary writes in called functions too. For you, that means the optimizer can eliminate writes to f in calculateFG when the calling code does not use f later on.
Perhaps it is best to turn the logic inside-out. Instead of computing a value (getValue()), passing it to both calculateF() and calculateG(), and passing the results to another place, you can change the code to pass the functions instead of computed values.
This way, if the client code does not need calculateF's value, it won't call it. The same with calculateG. If getValue is also expensive, you can call it once and bind or capture the value.
These are concepts used extensively in functional programming paradigm.
You could rewrite your calculateFG() function more or less like this:
auto getFG(double value)
{
auto val = getValue(value);
return {
[val]{ return calculateF(val); },
[val]{ return calculateG(val); }};
}
It sounds like your goal is to only perform the (potentially expensive) calculations of getValue(), f, and g as few times as possible given the caller's needs -- i.e. you don't want to perform any computations that the caller isn't going to use the results of.
In that case, it might be simplest to just implement a little class that does the necessary on-demand computations and caching, something like this:
#include <stdio.h>
#include <math.h>
class MyCalc
{
public:
MyCalc(double inputValue)
: _inputValue(inputValue), _vCalculated(false), _fCalculated(false), _gCalculated(false)
{
/* empty */
}
double getF() const
{
if (_fCalculated == false)
{
_f = calculateF();
_fCalculated = true;
}
return _f;
}
double getG() const
{
if (_gCalculated == false)
{
_g = calculateG();
_gCalculated = true;
}
return _g;
}
private:
const double _inputValue;
double getV() const
{
if (_vCalculated == false)
{
_v = calculateV();
_vCalculated = true;
}
return _v;
}
mutable bool _vCalculated;
mutable double _v;
mutable bool _fCalculated;
mutable double _f;
mutable bool _gCalculated;
mutable double _g;
// Expensive math routines below; we only want to call these (at most) one time
double calculateV() const {printf("calculateV called!\n"); return _inputValue*sin(2.14159);}
double calculateF() const {printf("calculateF called!\n"); return getV()*cos(2.14159);}
double calculateG() const {printf("calculateG called!\n"); return getV()*tan(2.14159);}
};
// unit test/demo
int main()
{
{
printf("\nTest 1: Calling only getF()\n");
MyCalc c(1.5555);
printf("f=%f\n", c.getF());
}
{
printf("\nTest 2: Calling only getG()\n");
MyCalc c(1.5555);
printf("g=%f\n", c.getG());
}
{
printf("\nTest 3: Calling both getF and getG()\n");
MyCalc c(1.5555);
printf("f=%f g=%f\n", c.getF(), c.getG());
}
return 0;
}
I think that it's best to write your code in a way that expresses what you are trying to accomplish.
If your goal is to make sure that certain calculations are only done once, use something like Jeremy's answer.
A good function should do only one thing. I would design like below.
class Calc {
public:
Calc(double value) : value{value}, val{getValue(value)} {
}
double calculateF() const;
double calculateG() const;
//If it is really a common usecase to call both together
std::pair<double, double> calculateFG() const {
return {calculateF(), calculateG()};
}
static double getValue(double value);
private:
double value;
double val;
};
To know whether compiler will optimize will depend on the rest of the code. For example, if there was a debug message like log_debug(...), that could affect dead code removal. Compiler can only get rid of the dead code if it can prove that the code has no side effects in compile time (Even if you force inline).
Other option is, you can mark the getValue function with special compiler specific attributes like pure or const. This can force the compiler to optimize the second call of getValue. https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#index-g_t_0040code_007bpure_007d-function-attribute-3348
How can I use macros as function pointers? I have no idea to solve this. I created a sketch (doesn't work, full of syntax errors) to show what I try to accomplish. Please help!
#define D0_OUT(x) (x/1024*100) //I want to use this for Pin0 calculation
#define D1_OUT(x) (x*1024) //I want to use this for Pin1 calculation
struct Pin {
CalcMethod *calcMethod; //int methodName(int x) { return MACRO(x); }
Pin(CalcMethod *calcMethodParam) {
calcMethod = calcMethodParam;
}
int calc(int x) {
return calcMethod(x);
}
};
#define PIN_COUNT 2
Pin *pins[PIN_COUNT];
void start() {
pins[0] = new Pin(D0_OUT); //use the D0_OUT macro to calculate
pins[1] = new Pin(D1_OUT); //use the D1_OUT macro to calculate
int pin0CalcResult=pins[0]->calc(5); // =5/1024*100
int pin1CalcResult=pins[1]->calc(6); // =6*1024
}
Macros are handled by the preprocessor. They don't exist in the compiled code, therefore there is no pointer.
There is one rule you should follow in modern code and that rule is "don't use macros for furnctions". Macros for functions are a relict that still has some good uses but they are very rare.
Just declare a normal function
int do_out(int x) {
return x / 1024 * 100;
}
Also see "static const" vs "#define" vs "enum"
You can, but not advisable, use macros as named lambdas. Thus
#define D0_OUT [](int x) { return x / 1024 * 100; }
#define D1_OUT [](auto x) { return x * 1024; }
and it should work.
D0_OUT example usable in C++11 and D1_OUT usable with C++14.
I know this is an old thread..
Assuming that you cannot just change the macro to be a function. Maybe it is part of a driver of library somewhere and you need to pass it into another function for some reason like unit testing. You can just wrap the macro within your .c file where you want to use it.
So this:
#define D0_OUT(x) (x/1024*100) //I want to use this for Pin0 calculation
becomes:
static int D0_OUT_wrapper(int x)
{
return D0_OUT(x);
}
So wrapper goes in like normal:
pins[0] = new Pin(D0_OUT_wrapper);
If you have full control of the code you are writing then just don't use macros.
Think about this code in C/C++:
bool cond = true;
while(cond){
std::cout << "cond is currently true!";
}
Is it possible to create a function that can be called like this?
myFunction(some_parameters_here){
//Code to execute, maybe use it for callbacks
myOtherFunction();
anotherFunction();
}
I know you can use function pointers and lambda functions, but I was wondering if you can. I'm pretty sure there is a way to do so, because how would while() exist?
while(condition) { expression } is not a function but a control structure / a separate language construct; it executes expression again and again as long as condition evaluates to true (i.e. something != 0).
an function definition of the form void myFunction(int someParameter) { expression }, in contrast, is executed only when it is called by another function.
Hope it helps a bit;
Caution: this solution comes without the guarantee that your code reviewer will like it.
We can use a trick similar to the one Alexandrescu uses for his SCOPE_EXIT macro (awesome one-hour conference, this bit is at 18:00).
The gist of it: a clever macro and a dismembered lambda.
namespace myFunction_detail {
struct Header {
// Data from the construct's header
};
template <class F>
void operator * (Header &&header, F &&body) {
// Do something with the header and the body
}
}
#define myPrefix_myFunction(a, b, c) \
myFunction_detail::Header{a, b, c} * [&]
Using it as follows:
myPrefix_myFunction(foo, bar, baz) {
}; // Yes, we need the semicolon because the whole thing is a single statement :/
... reconstitutes a complete lambda after macro expansion, and lands into myFunction_detail::operator* with acess to foo, bar, baz, and the body of the construct.
Suppose I have a function named caller, which will call a function named callee:
void caller()
{
callee();
}
Now caller might be called many times in the application, and you want to make sure callee is only called once. (kind of lazy initialization), you could implement it use a flag:
void caller()
{
static bool bFirst = true;
if(bFirst)
{
callee();
bFirst = false;
}
}
My opinion for this is it needs more code, and it needs one more check in every call of function caller.
A better solution to me is as follow: (suppose callee returns int)
void caller()
{
static int ret = callee();
}
But this can't handle the case if callee returns void, my solution is using the comma expression:
void caller()
{
static int ret = (callee(), 1);
}
But the problem with this is that comma expression is not popular used and people may get confused when see this line of code, thus cause problems for maintainance.
Do you have any good idea to make sure a function is only called once?
You could use this:
void caller()
{
static class Once { public: Once(){callee();}} Once_;
}
Thread-safe:
static boost::once_flag flag = BOOST_ONCE_INIT;
boost::call_once([]{callee();}, flag);
You could hide the function through a function pointer.
static void real_function()
{
//do stuff
function = noop_function;
}
static void noop_function()
{
}
int (*function)(void) = real_function;
Callers just call the function which will do the work the first time, and do nothing on any subsequent calls.
Your first variant with a boolean flag bFirst is nothing else that an explict manual implementatuion of what the compiler will do for you implictly in your other variants.
In other words, in a typical implementation in all of the variants you pesented so far there will be an additional check for a boolean flag in the generated machine code. The perfromance of all these variants will be the same (if that's your concern). The extra code in the first variant might look less elegant, but that doesn't seem to be a big deal to me. (Wrap it.)
Anyway, what you have as your first variant is basically how it is normally done (until you start dealing with such issues as multithreading etc.)
Inspired by some people, I think just use a macro to wrap comma expression would also make the intention clear:
#define CALL_ONCE(func) do {static bool dummy = (func, true);} while(0)
I'm working in C++ enviroment and:
a) We are forbidden to use exceptions
b) It is application/data server code that evaluates lot of requests of different kinds
I have simple class encapsulating result of server operation that is also used internally for lot of functions there.
class OpResult
{
.....
bool succeeded();
bool failed(); ....
... data error/result message ...
};
As I try to have all functions small and simple, lot of blocks like this are arising:
....
OpResult result = some_(mostly check)function(....);
if (result.failed())
return result;
...
The question is, is it bad practise to make macro looking like this and use it everywhere?
#define RETURN_IF_FAILED(call) \
{ \
OpResult result = call; \
if (result.failed()) \
return result; \
}
I understand that someone can call it nasty, but is there a better way?
What other way of handling results and avoiding lot of bloat code would you suggest?
It's a trade off. You are trading code size for obfuscation of the logic. I prefer to preserve the logic as visible.
I dislike macros of this type because they break Intellisense (on Windows), and debugging of the program logic. Try putting a breakpoint on all 10 return statements in your function - not the check, just the return. Try stepping through the code that's in the macro.
The worst thing about this is that once you accept this it's hard to argue against the 30-line monster macros that some programmers LOVE to use for commonly-seen mini-tasks because they 'clarify things'. I've seen code where different exception types were handled this way by four cascading macros, resulting in 4 lines in the source file, with the macros actually expanding to > 100 real lines. Now, are you reducing code bloat? No. It's impossible to tell easily with macros.
Another general argument against macros, even if not obviously applicable here, is the ability to nest them with hard to decipher results, or to pass in arguments that result in weird but compilable arguments e.g. the use of ++x in a macros that uses the argument twice. I always know where I stand with the code, and I can't say that about a macro.
EDIT: One comment I should add is that if you really do repeat this error check logic over and over, perhaps there are refactoring opportunities in the code. Not a guarantee but a better way of code bloat reduction if it does apply. Look for repeated sequences of calls and encapsulate common sequences in their own function, rather than addressing how each call is handled in isolation.
Actually, I prefer slightly other solution. The thing is that the result of inner call is not necessarily a valid result of an outer call. For example, inner failure may be "file not found", but the outer one "configuration not available". Therefore my suggestion is to recreate the OpResult (potentially packing the "inner" OpResult into it for better debugging). This all goes to the direction of "InnerException" in .NET.
technically, in my case the macro looks like
#define RETURN_IF_FAILED(call, outerresult) \
{ \
OpResult innerresult = call; \
if (innerresult.failed()) \
{ \
outerresult.setInner(innerresult); \
return outerresult; \
} \
}
This solution requires however some memory management etc.
Some purist argue that having no explicit returns hinders the readability of the code. In my opinion however having explicit RETURN as a part of the macro name is enough to prevent confusion for any skilled and attentive developer.
My opinion is that such macros don't obfuscate the program logic, but on the contrary make it cleaner. With such a macro, you declare your intent in a clear and concise way, while the other way seems to be overly verbose and therefore error-prone. Making the maintainers parse in mind the same construct OpResult r = call(); if (r.failed) return r is wasting of their time.
An alternative approach without early returns is applying to each code line the pattern like CHECKEDCALL(r, call) with #define CHECKEDCALL(r, call) do { if (r.succeeded) r = call; } while(false). This is in my eyes much much worse and definitely error-prone, as people tend to forget about adding CHECKEDCALL() when adding more code.
Having a popular need to do checked returns (or everything) with macros seems to be a slight sign of missing language feature for me.
As long as the macro definition sits in an implementation file and is undefined as soon as unnecessary, I wouldn't be horrified.
// something.cpp
#define RETURN_IF_FAILED() /* ... */
void f1 () { /* ... */ }
void f2 () { /* ... */ }
#undef RETURN_IF_FAILED
However, I would only use this after having ruled out all non-macro solutions.
After 10 years, I'm going to answer my own question to my satisfaction, if only I had a time machine ...
I encountered a similar situation many times in new projects. Even when exceptions were allowed, I don't want to always use them for "normal fails".
I eventually discovered a way to write these kind of statements.
For generic Result that includes message, I use this:
class Result
{
public:
enum class Enum
{
Undefined,
Meaningless,
Success,
Fail,
};
static constexpr Enum Undefined = Enum::Undefined;
static constexpr Enum Meaningless = Enum::Meaningless;
static constexpr Enum Success = Enum::Success;
static constexpr Enum Fail = Enum::Fail;
Result() = default;
Result(Enum result) : result(result) {}
Result(const LocalisedString& message) : result(Fail), message(message) {}
Result(Enum result, const LocalisedString& message) : result(result), message(message) {}
bool isDefined() const { return this->result != Undefined; }
bool succeeded() const { assert(this->result != Undefined); return this->result == Success; }
bool isMeaningless() const { assert(this->result != Undefined); return this->result == Enum::Meaningless; }
bool failed() const { assert(this->result != Undefined); return this->result == Fail; }
const LocalisedString& getMessage() const { return this->message; }
private:
Enum result = Undefined;
LocalisedString message;
};
And then, I have a special helper class in this form, (similar for other return types)
class Failed
{
public:
Failed(Result&& result) : result(std::move(result)) {}
explicit operator bool() const { return this->result.failed(); }
operator Result() { return this->result; }
const LocalisedString& getMessage() const { return this->result.getMessage(); }
Result result;
};
When these are combined, I can write code like this:
if (Failed result = trySomething())
showError(result.getMessage().str());
Isn't it beutiful?
I agree with Steve's POV.
I first thought, at least reduce the macro to
#define RETURN_IF_FAILED(result) if(result.failed()) return result;
but then it occurred to me this already is a one-liner, so there really is little benefit in the macro.
I think, basically, you have to make a trade off between write-ability and readability. The macro is definitely easier to write. It is, however, an open question whether it is also is easier to read. The latter is quite a subjective judgment to make. Still, using macros objectively does obfuscate code.
Ultimately, the underlying problem is that you must not use exceptions. You haven't said what the reasons for that decision are, but I surely hope they are worth the problems this causes.
Could be done with C++0x lambdas.
template<typename F> inline OpResult if_failed(OpResult a, F f) {
if (a.failed())
return a;
else
return f();
};
OpResult something() {
int mah_var = 0;
OpResult x = do_something();
return if_failed(x, [&]() -> OpResult {
std::cout << mah_var;
return f;
});
};
If you're clever and desperate, you could make the same kind of trick work with regular objects.
In my opinion, hiding a return statement in a macro is a bad idea. The 'code obfucation' (I like that term..! ) reaches the highest possible level. My usual solution to such problems is to aggregate the function execution at one place and control the result in the following manner (assuming you have 5 nullary functions):
std::array<std::function<OpResult ()>, 5> tFunctions = {
f1, f2, f3, f4, f5
};
auto tFirstFailed = std::find_if(tFunctions.begin(), tFunctions.end(),
[] (std::function<OpResult ()>& pFunc) -> bool {
return pFunc().failed();
});
if (tFirstFailed != tFunctions.end()) {
// tFirstFailed is the first function which failed...
}
Is there any information in result which is actually useful if the call fails?
If not, then
static const error_result = something;
if ( call().failed() ) return error_result;
would suffice.