On Sun, Mar 08, 2009 at 03:28:31PM +0200, Michael Widenius wrote:
> Roy> 4. How do we handle "modern" C++ (templates, namespaces, exceptions,...)
>
> Don't use them in the server code :)
> (Especially templates and exceptions)
One use for templates (mainly because g++ complains about {} in () for
C++ when you have -pedantic, which we build with in Drizzle) is to
enforce type safety of some macros.
e.g. I'm adding the below patch to Drizzle:
=== modified file 'drizzled/global.h'
--- drizzled/global.h 2009-03-11 07:24:40 +0000
+++ drizzled/global.h 2009-03-17 07:14:16 +0000
@@ -134,9 +134,39 @@
extern char _dig_vec_upper[];
extern char _dig_vec_lower[];
+#ifdef __cplusplus
+template <class T> void set_if_bigger(T &a, const T &b)
+{
+ if (a < b)
+ a=b;
+}
+
+template <class T> void set_if_smaller(T &a, const T &b)
+{
+ if (a > b)
+ a=b;
+}
+#else
+#ifdef __GNUC__
+#define set_if_bigger(a,b) do { \
+ const typeof(a) _a = (a); \
+ const typeof(b) _b = (b); \
+ (void) (&_a == &_b); \
+ if ((a) < (b)) (a)=(b); \
+ } while(0)
+#define set_if_smaller(a,b) do { \
+ const typeof(a) _a = (a); \
+ const typeof(b) _b = (b); \
+ (void) (&_a == &_b); \
+ if ((a) > (b)) (a)=(b); \
+ } while(0)
+
+#else
#define set_if_bigger(a,b) do { if ((a) < (b)) (a)=(b); } while(0)
-
#define set_if_smaller(a,b) do { if ((a) > (b)) (a)=(b); } while(0)
+#endif
+#endif
+
#define array_elements(A) ((size_t) (sizeof(A)/sizeof(A[0])))
/* Some types that is different between systems */
Why?
well, consider this test program:
#include <stdint.h>
#include <stdio.h>
#include <iostream>
using namespace std;
#ifdef FAIL
template <class T> void set_if_bigger(T &a, const T &b)
{
if (a < b)
a=b;
}
#else
#define set_if_bigger(a,b) do { if ((a) < (b)) (a)=(b); } while(0)
#endif
int main (int, char** )
{
uint8_t a= 42;
uint32_t b=2000;
set_if_bigger(a,b);
cout << (int)a << " " << (int)b << endl;
return 0;
}
Built with: -pedantic -ansi -std=c++0x -Wall -Wextra
For that, it builds and prints:
208 2000
If you add -DFAIL:
error: no matching function for call to set_if_bigger(uint8_t&, uint32_t&)
So the compiler catches it for you and forces you to think, rather than
find out at runtime.
The C macro part there does it for C code as well. So this header can be
included by both C++ and C code and (on gcc only for C) warn you when
you're doing something like this.
Haven't looked at the impl of std::min and std::max, but hopefully they
do something similar. The linux kernel min/max macros do - and they're
awesome :)
--
Stewart Smith