// define the macro
#define FATAL(S,...) qDebug("%s,%s,%d,%s:"##S,"[scribble]",__FILE__,__LINE__,__FUNCTION__,##__VA_ARGS__)
// call the macro
FATAL("not supported commandid:%d",cmdid);
While this code works under Windows (Qt with msvc2010), when I try to compile it under macOS (Qt with clang), I get the error:::
pasting formed "%s,%s,%d,%s:""not supported commandid:%d", an invalid
preprocessing token.
How can I make it work under macOS, or is there another way to do the same function?
The token ## only has special meaning of indicating an optional argument when it is placed between a comma and a variable argument: , ##__VA_ARGS__
This is an extension to the C language.
In your example this is done correctly for the second argument, but not for the first.
If you don't need the first argument to be optional simply remove the token ##:
#define FATAL(S,...) printf("%s,%s,%d,%s:"S, \
"[scribble]",__FILE__,__LINE__,__FUNCTION__,##__VA_ARGS__)
But the first argument can be optional too, using another macro to expand the string literal and the first argument, while making the first argument optional:
#include <stdlib.h>
#include <stdio.h>
#define MERGE_EXPAND( a , ... ) a __VA_ARGS__
#define MERGE( a , ... ) MERGE_EXPAND( a , ##__VA_ARGS__ )
#define FATAL(S,...) printf( MERGE( "%s,%s,%d,%s:",S), \
"[scribble]",__FILE__,__LINE__,__FUNCTION__,##__VA_ARGS__)
int main( void )
{
int cmdid = 12345;
FATAL();
puts( "" ) ;
FATAL( "first argument" );
puts( "" ) ;
FATAL( "first and second arguments: %d" , cmdid );
return EXIT_SUCCESS ;
}
Related
is it possible to reset the __COUNTER__ macro at the start of a header file to make its evaluation within the header file consistent over several compile units?
How about an enum?
enum { COUNTER_BASE = __COUNTER__ };
#define LOCAL_COUNTER (__COUNTER__ - COUNTER_BASE)
You can set BASE to __COUNTER__ at the top of your header file, and then use __COUNTER__ - BASE later on.
However, do this after you've included all necessary headers, because else thee result would depend on the use of __COUNTER__ within the header guards of those nested include files.
No, there is no way to reset that value.
Take a look at the GCC source that increments the counter:
case BT_COUNTER:
if (CPP_OPTION (pfile, directives_only) && pfile->state.in_directive)
cpp_error (pfile, CPP_DL_ERROR,
"__COUNTER__ expanded inside directive with -fdirectives-only");
number = pfile->counter++;
break;
And if you look arount this library, nowhere is the counter modified again. It is default initialized to 0 and then incremented at every use.
Note that the pfile, where the counter variable resides, represents the the preprocessor input, that in this case is the current compilation unit, not the actual file.
thanks to #Michael, and by using enum you can have complete usage of __COUNTER__ as below:
"source: ESF compiler extension"
//! >>>>>>>>>>>>>>>> Counter >>>>>>>>>>>>>>>>
#pragma region Counter
/* Counter
* Ex:
* <code>
CountOn(InitSteps);
int foo(void)
{
CountIt();
...
CountIt();
...
CountIt();
...
}
Counted(InitSteps);
* </code>
* */
#define CountOn(name) enum { name ## _BASE = __COUNTER__ }; const U8 name
#define CountIt(name) (U8)(__COUNTER__ - (name ## _BASE))
#define Counted(name) const U8 name = (U8)(__COUNTER__ - (name ## _BASE) -1);
/* alias of Counter
* Ex:
* <code>
TakeSteps(InitSteps);
int foo(void)
{
AddStep();
...
AddStep();
...
AddStep();
...
}
TotalSteps(InitSteps);
* </code>
* */
#define TakeSteps(name) CountOn(name)
/* this is invalid to read, want to get value ? use 'CountIt(name)' OR 'NextStep(name)' */
#define AddStep() do { __COUNTER__; } while (0);
#define TotalSteps(name) Counted(name)
/* better use of Counter (on format print 'step, total')
* 'step' starts at 1
* Ex:
* <code>
TakeSteps(InitSteps);
int foo(void)
{
printf(StepsPRT " Initializing system clock...", NextStep(InitSteps));
...
printf(StepsPRT " Loading configurations...", NextStep(InitSteps));
...
printf(StepsPRT " Applying...", NextStep(InitSteps));
...
}
TotalSteps(InitSteps);
* </code>
* */
#define NextStep(name) CountIt(name), name
#define StepsPRT "%d of %d"
#define NextStepP StepsPRT
#pragma endregion Counter
//! <<<<<<<<<<<<<<<< .Counter <<<<<<<<<<<<<<<<
Note: This is a question-with-answer in order to document a technique that others might find useful, and in order to perhaps become aware of others’ even better solutions. Do feel free to add critique or questions as comments. Also do feel free to add additional answers. :)
Visual C++ has always had a language extension __uuidof(classname) that can retrieve an UUID, a 128 bit Universally Unique Identifier, provided that the UUID’s been associated with the class via __declspec, which also is a Visual C++ language extension:
#include <guiddef.h> // GUID, another name for UUID
class
__declspec( uuid( "290ff5cb-3a21-4740-bfda-2697ca13deae" ) )
Foo
{};
#include <iostream>
using namespace std;
auto main()
-> int
{
cout << hex << __uuidof( Foo ).Data1 << endl; // 290ff5cb
}
MinGW g++ 4.8.2 (and possibly some earlier versions) supports __uuidof, but it does not support MSVC’s __declspec. Compiling the above with g++ 4.8.2 therefore fails, at least with the Nuwen distribution that I use. First g++ issues the warning “'uuid' attribute directive ignored”, and then one gets a linker error “undefined reference to _GUID const& __mingw_uuidof<Foo>()”.
The error hints at the way an UUID is associated with a class for g++, namely by specializing the function template __mingw_uuidof for the class.
Unfortunately the UUID specification is then of a form that’s radically different from the Visual C++ form. It’s numbers, not a string. And it’s not tucked in after the class or struct keyword, but follows a declaration of the class:
#include <guiddef.h> // GUID, another name for UUID
class Foo {};
template<>
auto __mingw_uuidof<Foo>()
-> GUID const&
{
static const GUID the_uuid =
{
0x290ff5cb, 0x3a21, 0x4740,
{ 0xbf, 0xda, 0x26, 0x97, 0xca, 0x13, 0xde, 0xae }
};
return the_uuid;
}
#include <iostream>
using namespace std;
auto main()
-> int
{
cout << hex << __uuidof( Foo ).Data1 << endl; // 290ff5cb
}
How can one associate an UUID with a class so that it will work with both compilers’ __uuidof, without redundancy, and preferably with the UUID as a direct sequence of digits (as with Visual C++)?
Up-front disclaimer: nothing of this has been extensively tested or reviewed. I just wrote it.
One possible unification approach is suggested by this fact:
A Visual C++ __declspec( uuid ) doesn’t need to be provided with the first declaration of a class: it can be applied after the first declaration.
E.g. Visual C++ code can look like this:
class Foo
{};
class __declspec( uuid( "290ff5cb-3a21-4740-bfda-2697ca13deae" ) ) Foo;
Thus a which-compiler-is-it sniffing macro CPPX_UUID_FOR can be defined as …
#if !defined( CPPX_UUID_FOR )
# if defined( _MSC_VER )
# define CPPX_UUID_FOR CPPX_MSVC_UUID_FOR
# elif defined( __GNUC__ )
# define CPPX_UUID_FOR CPPX_GNUC_UUID_FOR
# endif
#endif
and be invoked after the first declaration of the class:
#include <iostream>
using namespace std;
struct Foo {};
CPPX_UUID_FOR( Foo, "dbe41a75-d5da-402a-aff7-cd347877ec00" );
void test()
{
using cppx::uuid::operator<<;
cout << setw( 20 ) << "__uuidof: " << __uuidof( Foo ) << endl;
}
The macro implementation for Visual C++ is trivial:
#define CPPX_MSVC_UUID_FOR( name, spec ) \
class __declspec( uuid( spec ) ) name
The macro implementation for g++ is a bit more involved:
#define CPPX_GNUC_UUID_FOR( name, spec ) \
template<> \
inline \
auto __mingw_uuidof<name>() \
-> GUID const& \
{ \
using cppx::operator"" _uuid; \
static constexpr GUID the_uuid = spec ## _uuid; \
\
return the_uuid; \
} \
\
template<> \
inline \
auto __mingw_uuidof<name*>() \
-> GUID const& \
{ return __mingw_uuidof<name>(); } \
\
static_assert( true, "" )
… where the static_assert only serves to support a final semicolon in the invocation.
The user defined literal is not strictly necessary, but I thought it was interesting to do it.
cppx::operator"" _uuid is defined thusly, in namespace cppx:
namespace detail {
CPPX_CONSTEXPR
auto uuid_from_spec( char const* const s, size_t const size )
-> cppx::Uuid
{
return (
size == 36? cppx::uuid::from(
reinterpret_cast<char const (&)[37]>( *s )
) :
cppx::fail(
"An uuid spec must be 36 chars, like"
" \"dbe41a75-d5da-402a-aff7-cd347877ec00\""
)
);
}
} // namespace detail
#if !(defined( _MSC_VER ) || defined( NO_USER_LITERALS ))
CPPX_CONSTEXPR
auto operator"" _uuid( char const* const s, size_t const size )
-> cppx::Uuid
{ return detail::uuid_from_spec( s, size ); }
#endif
where cppx::uuid::from is defined earlier in namespace cppx::uuid:
inline CPPX_CONSTEXPR
auto from( char const (&spec)[37] )
-> Uuid
{ return Initializable( ce, spec ); }
where ce is just a constructor tag, of enumeration type Const_expr, that selects the constexpr constructor of the uuid::Initializable class:
struct Initializable: Uuid
{
explicit CPPX_CONSTEXPR
Initializable( Const_expr, char const (&spec)[37] )
: Uuid( {
// Data1
(((((((((((((
static_cast<unsigned long>( nybble_from_hex( spec[0] ) )
<< 4) | nybble_from_hex( spec[1] ))
<< 4) | nybble_from_hex( spec[2] ))
<< 4) | nybble_from_hex( spec[3] ))
<< 4) | nybble_from_hex( spec[4] ))
<< 4) | nybble_from_hex( spec[5] ))
<< 4) | nybble_from_hex( spec[6] ))
<< 4) | nybble_from_hex( spec[7] ),
// Data2
static_cast<unsigned short>(
(((((
static_cast<unsigned>( nybble_from_hex( spec[9] ) )
<< 4) | nybble_from_hex( spec[10] ))
<< 4) | nybble_from_hex( spec[11] ))
<< 4) | nybble_from_hex( spec[12] )
),
// Data 3
static_cast<unsigned short>(
(((((
static_cast<unsigned>( nybble_from_hex( spec[14] ) )
<< 4) | nybble_from_hex( spec[15] ))
<< 4) | nybble_from_hex( spec[16] ))
<< 4) | nybble_from_hex( spec[17] )
),
// Data 4
{
static_cast<unsigned char>( byte_from_hex( spec[19], spec[20] ) ),
static_cast<unsigned char>( byte_from_hex( spec[21], spec[22] ) ),
static_cast<unsigned char>( byte_from_hex( spec[24], spec[25] ) ),
static_cast<unsigned char>( byte_from_hex( spec[26], spec[27] ) ),
static_cast<unsigned char>( byte_from_hex( spec[28], spec[29] ) ),
static_cast<unsigned char>( byte_from_hex( spec[30], spec[31] ) ),
static_cast<unsigned char>( byte_from_hex( spec[32], spec[33] ) ),
static_cast<unsigned char>( byte_from_hex( spec[34], spec[35] ) )
}
} )
{}
explicit
Initializable( char const (&spec)[37] )
: Uuid()
{
for( int i = 0; i < 8; ++i )
{
Uuid::Data1 = (Uuid::Data1 << 4) | nybble_from_hex( spec[i] );
}
assert( spec[8] == '-' );
for( int i = 9; i < 13; ++i )
{
Uuid::Data2 = (Uuid::Data2 << 4) | nybble_from_hex( spec[i] );
}
assert( spec[13] == '-' );
for( int i = 14; i < 18; ++i )
{
Uuid::Data3 = (Uuid::Data3 << 4) | nybble_from_hex( spec[i] );
}
assert( spec[18] == '-' );
for( int i = 19; i < 23; i += 2 )
{
Uuid::Data4[(i - 19)/2] = byte_from_hex( spec[i], spec[i + 1] );
}
assert( spec[23] == '-' );
for( int i = 24; i < 36; i += 2 )
{
Uuid::Data4[2 + (i - 24)/2] = byte_from_hex( spec[i], spec[i + 1] );
}
}
};
The two constructors mainly differ in how easy it is to judge the correctness or not of the code, but the last one (I wrote that first!) also has useful assert statements. I'm not sure how to best do such assertions for the constexpr constructor. Or even whether that is doable, which is one reason why there are two constructors instead of just one.
Oh, the << invocations here are just good old left-shifts, not fancy custom operator-notation output or stream or store operations. :)
The definitions of nybble_from_hex and byte_from_hex are pretty trivial, but the fail function is a bit subtle. In spite of appearances it’s not a constexpr function. Instead, it’s a non-returning function. C++11 has a notation to express that, [[noreturn]], but as far as I know neither Visual C++ nor g++ supports that yet. So instead I use compiler specific annotations, like this:
#if !defined( CPPX_NORETURN )
# if defined( _MSC_VER )
# define CPPX_NORETURN __declspec( noreturn )
# elif defined( __GNUC__ )
# define CPPX_NORETURN __attribute__((noreturn))
# else
# define CPPX_NORETURN [[noreturn]]
# endif
#endif
and then fail can be coded up simply as e.g.
struct Whatever
{
template< class Type >
CPPX_CONSTEXPR operator Type () const { return Type(); }
};
inline
CPPX_NORETURN
auto fail( string const& s )
-> Whatever
{ throw runtime_error( s ); }
I found it non-trivial (and possibly impossible) to express fail as a constexpr function when it has std::string argument, and as an ordinary function calls of it suppressed the constexpr property. The non-returning variant works OK with g++. However, I’m not sure what the standard has to say about this.
I've gone a bit deep with template programming in my latest library rewrite, and so I made template that assembles bitmasks which I want to use as a method parameter initializer:
test_scanner( unsigned int avec = CtrlVec<'\n','\r'>::mask ) ;
This works with GCC 4.8, but I get a series of errors from clang 3.2:
error: expected parameter declarator
error: expected ')'
error: expected '>'
Putting a () around CtrlVec fixes the problem. What I am curious is, does it work in later versions of Clang or should I submit this as a possible error in the compiler, or am I doing something wrong?
The entire test case is here:
namespace test
{
// template magic for building a bit mask from control characters
template <char...> struct CtrlVec ;
template <char c> struct CtrlVec<c>
{
static_assert( ( c < 0x20 ), "Only for control characters" ) ;
enum { mask = ( 1 << c ) } ;
} ;
template <char c, char... cs> struct CtrlVec<c, cs...>
{
static_assert( ( c < 0x20 ), "Only for control characters" ) ;
enum { mask = ( 1 << c ) | CtrlVec<cs...>::mask } ;
} ;
static_assert( CtrlVec<'\0', '\001', '\002'>::mask == 0x7, "") ;
///
class test_scanner
{
public:
// this version works fine in GCC, but gives an error in Clang 3.2
test_scanner( unsigned int avec = CtrlVec<'\n','\r'>::mask ) ;
// adding the () makes it work
test_scanner( int good, unsigned int avec = ( CtrlVec<'\n','\r'>::mask ) ) ;
} ;
} ;
int main() {}
or you can pull it from github:
https://github.com/woolstar/test/blob/master/misc/testinitargs.cpp
I want to create a macro that will accept arbitrary code block as its parameter like
FOR_VECTOR( type, vect, code_block ) \
for( vector<type>::iterator i=vect.begin(); i!=vect.end(); ++i ) { \
code_block; \
}
The problem is the code block in parameter, which may contain arbitrary number of , and ) characters.
Is there any good solution?
There are a number of possible solutions.
If you need only one expression (not a full-fashioned code block) - you can just enclose it in ( and )
FOR_VECTOR( int, v, (func(i,1)) )
will work - (func(i,1)) is treated like single macro argument
Another partial solution is variadic macros, if your preprocessor supports them.
You can define macros
#define COMMA ,
#define LPAR (
#define RPAR )
and use them to form your code block insted of real ( , and )
FOR_VECTOR( int, v, func LPAR i COMMA 1 RPAR )
It is not very readable though.
Or you can do a trick with commenting out quotes of a string literal after macro substitution:
FOR_VECTOR( type, vect, code_block ) \
for( vector<type>::iterator i=vect.begin(); i!=vect.end(); ++i ) { \
/code_block/; \
}
FOR_VECTOR( int, v, *"*/ func(i,1); proc(i,2); /*"* )
As #mas.morozov mentioned, you can use variadic macros:
#include <iostream>
#include <vector>
#define FOR_VECTOR( type, vect, ... ) \
for( std::vector<type>::iterator i=vect.begin(); i!=vect.end(); ++i ) { \
__VA_ARGS__ \
}
int main()
{
std::vector<int> v = {1, 2, 3, 4, 5, 6};
FOR_VECTOR(int, v, {
std::cout << *i << std::endl;
})
}
You can play with it online here: https://godbolt.org/z/oLWV-z
I found that solution here: https://mort.coffee/home/obscure-c-features/
You can also make a more generic FOR_CONTAINER macro:
#include <iostream>
#include <vector>
#define FOR_CONTAINER( container, ... ) \
for( decltype(container)::iterator i=container.begin(); i!=container.end(); ++i ) { \
__VA_ARGS__ \
}
int main()
{
std::vector<int> v = {1, 2, 3, 4, 5, 6};
FOR_CONTAINER(v, {
std::cout << *i << std::endl;
})
}
Try it here: https://godbolt.org/z/9Gzqja
I have this macro from someone's code:
#define Q_DEF_PROTOTYPE( Type, Name ) Type (*Name)
#define COPY_FP( pDest, pSrc ) (*((void**)(&(pDest)))) = ((void*)(pSrc))
#define LIB_QUERY(lib_handle, proc) dlsym(lib_handle, proc)
#define Q_DEF_PROTOTYPE( Type, Name ) \
COPY_FP( p->Name, LIB_QUERY( g_library, STRINGIZE(FUNC(Name)) ) ); \
void dummy_##Name
Not sure, what "void dummy_##Name" does? Thanks.
It replace the ##Name with the value of Name parameter as string.
Q_DEF_PROTOTYPE(myType, objectName) => void dummy_objectName