Tuesday, May 14, 2019

Digest for comp.lang.c++@googlegroups.com - 21 updates in 6 topics

Thiago Adams <thiago.adams@gmail.com>: May 14 06:56AM -0700

C++ is always moving into a directing of removing the need for preprocessor.
Is it still necessary? Where do you need/use macros?
 
I am not considering #ifdef, #error etc, just macro expansion.
 
My answer for C++:
 
- assert
- We have REQUIRE_POINTER(pPointer) macro that returns an error if
the pointer is null.
- I am still using SIZEOF macro
- __FILE__ __LINE___
- Literal strings (I prefer macros than const char * )
- constants ( I am not using constexpr yet)
-
Bonita Montero <Bonita.Montero@gmail.com>: May 14 05:17PM +0200

> - I am still using SIZEOF macro
 
Before I used this ...
 
template<typename T, size_t N>
inline constexpr
size_t array_size( T (&)[N] )
{
return N;
}
 
... I write this ...
 
#define array_size(a) (sizeof(a) / sizeof(a[0]))
red floyd <dont.bother@its.invalid>: May 14 09:12AM -0700

On 5/14/2019 6:56 AM, Thiago Adams wrote:
> - Literal strings (I prefer macros than const char * )
> - constants ( I am not using constexpr yet)
> -
 
I use it to keep independent stuff in sync (though that's generally
in C, not C++)...
 
e.g.:
 
#define LIST_OF_STUFF \
ITEM(this1, value1, text1), \
ITEM(this2, value2, text2), // and so forth
 
#define ITEM(x, y, z) x = y
enum some_enum {
LIST_OF_STUFF
};
 
#undef ITEM
#define ITEM(x, y, z) #z
const char *const messages {
LIST_OF_STUFF
};
 
#undef ITEM
red floyd <dont.bother@its.invalid>: May 14 09:13AM -0700

On 5/14/2019 9:12 AM, red floyd wrote:
>   LIST_OF_STUFF
> };
 
> #undef ITEM
 
That is to say, as an X Macro.
Thiago Adams <thiago.adams@gmail.com>: May 14 09:45AM -0700

On Tuesday, May 14, 2019 at 1:12:32 PM UTC-3, red floyd wrote:
...
> I use it to keep independent stuff in sync (though that's generally
> in C, not C++)...
 
Very nice.
 
Since you mentioned C, In C I use a little more macros.
 
- X_INIT to initialize structs (In C++ this is not needed)
struct X x = X_INIT;
- constants
- Sometimes FOREACH
- custom Malloc/Free
- Unit Tests (just to simplify syntax)
-
Paavo Helde <myfirstname@osa.pri.ee>: May 14 08:52PM +0300

On 14.05.2019 16:56, Thiago Adams wrote:
 
> C++ is always moving into a directing of removing the need for preprocessor.
> Is it still necessary? Where do you need/use macros?
 
> I am not considering #ifdef, #error etc, just macro expansion.
 
1. For __FILE__, __LINE__:
 
#define MY_ASSERT(x) \
if (!(x)) throw AssertException(__FILE__, __LINE__, #x);
 
MY_ASSERT(n>0);
 
2. For avoiding forgetting to define a mutex lock variable:
 
#define BOOST_MUTEX_SCOPED_LOCK(mx) \
boost::mutex::scoped_lock boost_mutex_lock(mx)
 
boost::mutex mx1;
BOOST_MUTEX_SCOPED_LOCK(mx1);
 
// instead of non-functional
// boost::mutex::scoped_lock(mx1);
 
3. For dispatching execution to templates at run time:
 
#define DISPATCH_NUMERIC(ELEMTYPE,FUNCTION,ARGS) \
switch(ELEMTYPE) {\
case UInt8: {typedef uint8_t dispatch_t; FUNCTION ARGS; break;}\
case UInt16: {typedef uint16_t dispatch_t; FUNCTION ARGS; break;}\
case UInt32: {typedef uint32_t dispatch_t; FUNCTION ARGS; break;}\
case UInt64: {typedef uint64_t dispatch_t; FUNCTION ARGS; break;}\
case Int8: {typedef int8_t dispatch_t; FUNCTION ARGS; break;}\
case Int16: {typedef int16_t dispatch_t; FUNCTION ARGS; break;}\
case Int32: {typedef int32_t dispatch_t; FUNCTION ARGS; break;}\
case Int64: {typedef int64_t dispatch_t; FUNCTION ARGS; break;}\
case Float: {typedef float dispatch_t; FUNCTION ARGS; break;}\
case Double: {typedef double dispatch_t; FUNCTION ARGS; break;}\
default: throw Exception("Not implemented");\
};
 
template<typename T> foo(const T* source, size_t len, int param1);
 
DISPATCH_NUMERIC(
myvec.ElemType(), foo, (myvec.Data<dispatch_t>(), myvec.Size(), 42));
 
4. For compiler-specific stuff.
 
#ifdef _MSC_VER
#define DI_FOO __declspec(dllexport)
#else
#define DI_FOO

No comments: