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.
Related
I implement a bridge from Ocaml to C++. As I know, only functions that bound in the OCaml side with using external keyword should be defined as C function (it is necessary for linker). So they should be contained in extern "C" { ... } block. Except for this point, I can use C++ code as I want (include using in functions declared in **extern "C" ** block).
To improve readability I want to wrap macros from "caml/mlvalues.h" like the following
namespace Caml {
namespace Value {
int to_int(value x) { return Int_val(x); }
value of_int(int x) { return Val_int(x); }
...
}
}
and to use Caml::Value::to_int and Caml::Value::of_int instead of original Int_val and Val_int. But it looks dangerous for me because of macros, bitwise copying, and scopes. Is it safe to use a facade like described above?
I do not see anything wrong with your wrappers for Int_val and Val_int. The wrapper for the Field macro would need to return an l-value, but there is nothing difficult about it:
value &field(value *x, int y) { return Field(x, y); }
I suppose the more interesting code would come from a wrapper around Is_block so as to make it a bit more idiomatic:
value *as_block(value x)
{ if (Is_block(x)) return (value *)x;
else return nullptr; }
// usage:
if (value *ptr = as_block(x)) {
foo(field(ptr, 0));
} else {
bar(to_int(x));
}
For extra type safety, you could replace the type value * of field and as_block by an opaque pointer:
struct block;
block *as_block(value) ...
value &field(block *, int) ...
The value functions should be declared as const expression where possible and static inline otherwise. Apart from that wrapping them in other function is perfectly fine.
The CAMLparam macros on the other hand open a scope that is closed by CAMLreturn macros. And it's annoying that you have to specify the number of arguments for it anway.
You should rewrite them from scratch in C++ using vardiac templates and RAII style. So instead of opening a new scope and declaring some hidden variables you should have a real object that registers the arguments with the GC in the constructor and unregisters them in the destructor.
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.
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.
I was just experimenting with C++. I was trying to write a small macro so that all the functions that I define are automatically stored in a map so that I can query, at run time, what functions exist and run them too. The code is as follows:
#include <map>
using namespace std;
typedef void (*funcPointer)();
map <char*, funcPointer> funcList;
#define Function(x) void x() { funcList[#x] = x;
#define End }
I was used funcPointer and End only for easy readability and implementation. Now, I can define a function as
Function(helloWorld)
cout << "Hello World";
End
Now, to read the function names as a list and run all the functions, I use the following code:
int main() {
//helloWorld();
for (map<char*, funcPointer>::iterator I = funcList.begin(); I != funcList.end(); I++) {
printf(I->first);
I->second();
}
getchar();
return 0;
}
The problem is, if I keep the first line of main() (helloWorld();) commented, the compiler doesn't compile the function and skips it for optimization, as according to the compiler, it is never used. So, the function list turns up empty. If, instead, I call the function once, every thing works perfectly, except that it prints "Hello World" twice. Also, I wrote the macro specifically so I do not have to do that.
So, is there any way that I can force the compiler to compile a function even if it is not used?
The problem is that the code to register the function is inside the function, so won't happen unless you call the function. You might instead register it by initialising a global variable, which will happen automatically before main begins. This might look something like
struct funcRegistration {
funcRegistration(char * name, funcPointer func) {funcList[name] = func;}
};
#define Function(x) \
void x(); \
funcRegistration x##_registration(#x, x); \
void x() {
The compiler compiles the function, however your map won't be populated unless its called.
Because funcList[#x] = x; comes inside the function block { } after macro expansion.
Suppose I have a class Utility in a file utility.h:
class Utility {
public:
static double longDescriptiveName(double x) { return x + 42; }
};
And then I find that I use the function longDescriptiveName(...) a LOT. So like an irresponsible C++ programmer that I am when I've had too much coffee, I create a new file utilitymacros.h and add the following there:
#define ldn Utility::longDescriptiveName
Now I include "utilitymacros.h" in any *.cpp where I use ldn(...) and my heart is filled with joy over how much more convinient it is to type 3 letters vs 28.
Question: Is there a safer (more proper) way of doing this than with #define?
I've noticed that I have to include "utilitymacros.h" after including boost headers, which I obviously don't like because it's a sign of clashes (though the Boost errors I get are not very clear as to what the clash is).
Clarification 1: On Code Readability
In case you might say that this negatively affects code readability, I assure you it does not, because it's a small set of functions that are used A LOT. An example that is widely know is stoi for stringToInteger. Another is pdf for probabilityDensityFunction, etc. So if I want to do the following, stoi is more readable in my opinion:
int x = stoi(a) + stoi(b) + stoi(c) + stoi(d);
Than:
int x = Utility::stringToInteger(a) + Utility::stringToInteger(b)
+ Utility::stringToInteger(c) + Utility::stringToInteger(d);
Or:
int x = Utility::stringToInteger(a);
x += Utility::stringToInteger(b);
x += Utility::stringToInteger(c);
x += Utility::stringToInteger(d);
Clarification 2: Editor Macro
I use Emacs as my IDE of choice and a Kinesis keyboard so you KNOW I use a ton of keyboard macros, custom keyboard shortcuts, as well as actually modifying what I see in the editor vs what's actually stored in the h/cpp file. But still, I feel like the simplicity and visual readability (as argued above) of using a function abbreviation in a few select cases really is the result I'm looking for (this is certainly subject to a degree).
Instead of macro, you could write inline function that forwards the call to the actual function:
inline double ldn(double x)
{
return Utility::longDescriptiveName(x);
}
That is certainly safer than macro.
You could use a function reference:
double (&ldn)(double) = Utility::longDescriptiveName;
How about configuring a snippit/macro/similar thing in your text editor? This way you only have to type ldn or something like that and the code doesn't have to run through the preprocessor risking difficult to find bugs later.
I don't know if this helps, but I think part of the problem may be the use of overly general namespaces (or class names, in this case), such as Utility.
If instead of Utility::stringToInteger, we had
namespace utility {
namespace type_conversion {
namespace string {
int to_int(const std::string &s);
}
}
}
Then the function could locally be used like this:
void local_function()
{
using namespace utility::type_conversion::string;
int sum = to_int(a) + to_int(b) + to_int(c) + to_int(d);
}
Analogously, if classes/structs and static functions are used (and there can be good reasons for this), we have something like
strut utility {
struct type_conversion {
struct string {
static int to_int(const std::string &s);
};
};
};
and the local function would look something like this:
void local_function()
{
typedef utility::type_conversion::string str;
int sum = str::to_int(a) + str::to_int(b)
+ str::to_int(c) + str::to_int(d);
}
I realize I am not telling you anything about syntax you didn't know already; it's more a reminder of the fact that the organization and structure of namespaces and classes itself plays an important role in making code more readable (and writable).
One alternative is to rename your function and put it in a namespace instead of a class, since it is static anyway. utility.h becomes
namespace Utility {
// long descriptive comment
inline double ldn(double x) { return x + 42; }
}
Then you can put using namespace Utility; in your client code.
I know there are lots of style guides out there saying short names are a bad thing, but I don't see the point of obeying some style and then circumventing it.
You can use alias template (since C++11).
using shortName = my::complicate::function::name;