alericardi / arduino

Automatically exported from code.google.com/p/arduino
0 stars 0 forks source link

Replace #define'd macros (abs(), constrain(), etc) with templated, inlined functions (for C++) #51

Open GoogleCodeExporter opened 9 years ago

GoogleCodeExporter commented 9 years ago
including stdlib.h from a library blows up with a

   /avr/include/stdlib.h:111: error: expected unqualified-id before 'int'

This is because wiring.h tries to define abs() itself. Wiring.h tries to
disable stdlib.h's abs, but fails. abs() in stdlib.h is defined as a
external function, but wiring.h tries to undefine it as a macro with:

   // undefine stdlib's abs if encountered
   #ifdef abs
   #undef abs
   #endif

I don't think there is any reason to override the default abs() function
anymore. There use to be a nasty bug
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=34130 .

--------------------

Also, there are problems with the abs() function that this would fix.

As documented at http://arduino.cc/en/Reference/Abs, the macro-ness of the
abs() means
   abs(a++);
doesn't work as expected.

Also there is a inefficiency in the current implementation:
   #define abs(x) ((x)>0?(x):-(x))
this really should be:
   #define abs(x) ((x)>=0?(x):-(x))
because there is no reason to negate zero. This wastes a cycle when you use
abs() with a zero.

Original issue reported on code.google.com by gabebear@gmail.com on 6 Jul 2009 at 5:01

Attachments:

GoogleCodeExporter commented 9 years ago
This version of wiring.h removes all the dangerous macros that use a parameter 
more
than once and replaces them with C++ templates.

The C macros are commented out, but are in an ifdef that would only include 
them in C
programs. No arduino libraries written in C seem to rely on these functions, so 
it
would probably be best to leave them out of C.

Considering that Arduino is supposed to be easy to pick up, I think this is a 
good idea

Original comment by gabebear@gmail.com on 6 Jul 2009 at 2:37

Attachments:

GoogleCodeExporter commented 9 years ago

Original comment by dmel...@gmail.com on 14 Jul 2009 at 10:03

GoogleCodeExporter commented 9 years ago
What do these templated functions do if you pass them parameters of different 
types (e.g. an int and a float)?  

Original comment by dmel...@gmail.com on 15 Aug 2009 at 8:38

GoogleCodeExporter commented 9 years ago

Original comment by dmel...@gmail.com on 11 Oct 2011 at 3:39

GoogleCodeExporter commented 9 years ago
I've been out of the loop here for awhile, but I can't imagine these templates 
having any problem with any sane type. I haven't been using Arduino much 
lately. I could spin back up if you want me to do something though.

As a C/C++/ObjC programmer these kinds of problems really annoy me so I would 
like to get it fixed even though I've moved to other platforms.

Original comment by gabebear@gmail.com on 11 Oct 2011 at 4:44

GoogleCodeExporter commented 9 years ago
I think that using C++ templates is a VERY BAD idea.
There are other ways to handle this that work for both C and C++.
Remember that these headers files are being use for both C and C++ so any 
solution
really needs to work for both.
The problem is that the existing macros are too wimpy.
Here is the proper way to do this:
http://arduino.cc/forum/index.php/topic,84364.msg640438.html#msg640438

Original comment by bperry...@gmail.com on 9 Jun 2012 at 6:49

GoogleCodeExporter commented 9 years ago
no, don't use DEFINE for macros and constants in c++ mode as it _breaks_ code.

two examples:

struct vector2{ /*..*/ };
float abs(vector2) { /*..*/ } // breaks function overloading

and

namespace some_ns { const float PI=3.14....; } // invades all namespaces

because of these defines i'm currently forced to use a lot of workarounds

Original comment by markus.w...@gmail.com on 18 Aug 2013 at 12:47