Check some compile-time definitions at compile time with older C++ implementations - c++

When working on a large legacy code base, I today suspected a duplicate definition, but the dependency was not obvious to me human since it depended on a lots of compile-time calculations.
enum { MAX_ITEMS = 4 }; // defined somewhere in my code universe
enum { ITEMS_MAX = COMPLICATED_CALCULATIONS }; // somewhere else
I remembered some cases with analogous sizeof questions, when I let the compiler speak.
I usually put some ad-hoc formulations like this in the code (in the IDE), then I press [Alt]+[F9]:
void check() {
char bla[MAX_ITEMS == ITEMS_MAX]; // compiler-error shows difference
// ...but it causes a compiler warning about bla being never used
}
...and that's only because my compiler (Borland C++ 5.6.4) lazy evaluates the typedef for arrays with non-literal dimension:
typedef char bla[0]; // immediate compiler error
typedef char bla[0 != 0]; // obvious, but no compiler error HERE
Is there a really easy-to-memorize way for checks like this? And, please don't blame an old brave compiler ;-)

This works:
#define STATIC_ASSERT(x) typedef char foo[(x) ? 1 : -1];
I actually use the following setup borrowed from Boost, the purpose of this is to give each foo its own line number (otherwise a multiple definition error can happen):
#define BOOST_JOIN( X, Y ) BOOST_DO_JOIN( X, Y )
#define BOOST_DO_JOIN( X, Y ) BOOST_DO_JOIN2(X,Y)
#define BOOST_DO_JOIN2( X, Y ) X##Y
#define STATIC_ASSERT(x) \
typedef char BOOST_JOIN(violation_on_line_,__LINE__) [(x) ? 1 : -1];

You should try if BOOST_STATIC_ASSERT works on your compiler.

Related

Generating BitCount LUT at compile time

Let's say that I need to create a LUT containing precomputed bit count values (count of 1 bits in a number) for 0...255 values:
int CB_LUT[256] = {0, 1, 1, 2, ... 7, 8};
If I don't want to use hard-coded values, I can use nice template solution How to count the number of set bits in a 32-bit integer?
template <int BITS>
int CountBits(int val)
{
return (val & 0x1) + CountBits<BITS-1>(val >> 1);
}
template<>
int CountBits<1>(int val)
{
return val & 0x1;
}
int CB_LUT[256] = {CountBits<8>(0), CountBits<8>(1) ... CountBits<8>(255)};
This array is computed completely at compile time. Is there any way to avoid a long list, and generate such array using some kind of templates or even macros (sorry!), something like:
Generate(CB_LUT, 0, 255); // array declaration
...
cout << CB_LUT[255]; // should print 8
Notes. This question is not about counting 1 bits in an number, it is used just as example. I want to generate such array completely in the code, without using external code generators. Array must be generated at compile time.
Edit.
To overcome compiler limits, I found the following solution, based on
Bartek Banachewicz` code:
#define MACRO(z,n,text) CountBits<8>(n)
int CB_LUT[] = {
BOOST_PP_ENUM(128, MACRO, _)
};
#undef MACRO
#define MACRO(z,n,text) CountBits<8>(n+128)
int CB_LUT2[] = {
BOOST_PP_ENUM(128, MACRO, _)
};
#undef MACRO
for(int i = 0; i < 256; ++i) // use only CB_LUT
{
cout << CB_LUT[i] << endl;
}
I know that this is possibly UB...
It would be fairly easy with macros using (recently re-discovered by me for my code) Boost.Preprocessor - I am not sure if it falls under "without using external code generators".
PP_ENUM version
Thanks to #TemplateRex for BOOST_PP_ENUM, as I said, I am not very experienced at PP yet :)
#include <boost/preprocessor/repetition/enum.hpp>
// with ENUM we don't need a comma at the end
#define MACRO(z,n,text) CountBits<8>(n)
int CB_LUT[256] = {
BOOST_PP_ENUM(256, MACRO, _)
};
#undef MACRO
The main difference with PP_ENUM is that it automatically adds the comma after each element and strips the last one.
PP_REPEAT version
#include <boost/preprocessor/repetition/repeat.hpp>
#define MACRO(z,n,data) CountBits<8>(n),
int CB_LUT[256] = {
BOOST_PP_REPEAT(256, MACRO, _)
};
#undef MACRO
Remarks
It's actually very straightforward and easy to use, though it's up to you to decide if you will accept macros. I've personally struggled a lot with Boost.MPL and template techniques, to find PP solutions easy to read, short and powerful, especially for enumerations like those. Additional important advantage of PP over TMP is the compilation time.
As for the comma at the end, all reasonable compilers should support it, but in case yours doesn't, simply change the number of repetitions to 255 and add last case by hand.
You might also want to rename MACRO to something meaningful to avoid possible redefinitions.
I like to do it like this:
#define MYLIB_PP_COUNT_BITS(z, i, data) \
CountBits< 8 >(i)
int CB_LUT[] = {
BOOST_PP_ENUM(256, MYLIB_PP_COUNT_BITS, ~)
};
#undef MYLIB_PP_COUNT_BITS
The difference with BOOST_PP_REPEAT is that BOOST_PP_ENUM generates a comma-separated sequence of values, so no need to worry about comma's and last-case behavior.
Furthermore, it is recommended to make your macros really loud and obnoixous by using a NAMESPACE_PP_FUNCTION naming scheme.
a small configuration thing is to omit the [256] in favor of [] in the array size so that you can more easily modify it later.
Finally, I would recommend making your CountBit function template constexpr so that you also can initialize const arrays.

Validate an argument is ARRAY type in c/c++ pre processing macro on compile time [duplicate]

This question already has answers here:
Array-size macro that rejects pointers
(9 answers)
Closed 4 years ago.
Is there any way to validate on compile time in a c macro that an argument is an array ?
e.g in this two macros:
#define CLEAN_ARRAY(arr) \
do { \
bzero(arr, sizeof(arr)); \
} while (0)
And
#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
I tried something using CTC(X) macro , but couldn't find any way to validate/warn if arr isn't an array.
Here's a solution in pure C which invokes no undefined behavior:
#define IS_INDEXABLE(arg) (sizeof(arg[0]))
#define IS_ARRAY(arg) (IS_INDEXABLE(arg) && (((void *) &arg) == ((void *) arg)))
If you need to ensure that the value is an array (then cause a compile time error if not), you can simply use it as an initializer to an enum statement (or a static variable), like this:
static int __ ## arg ## _is_array = IS_ARRAY(arg); // works for an array, fails for pointer.
I'm not entirely sure what will happen with VLA's, but playing around a bit should find that answer out rather fast.
Old answers:
Since this is tagged C (and GCC), I will attempt a solution here:
#define IS_ARRAY(arg) __builtin_choose_expr(__builtin_types_compatible_p(typeof(arg[0]) [], typeof(arg)), 1, 0)
Another solution, using C11's _Generic feature & typeof:
#define IS_ARRAY(arg) _Generic((arg),\
typeof(arg[0]) *: 0,\
typeof(arg[0]) [sizeof(arg) / sizeof(arg[0])]: 1\
)
Basically, all it does is use some fancy features of GCC to determine if the type of the argument is compatible with an array of the type of the argument's elements. It will return 0 or 1, and you could replace the 0 with something that creates a compile time error if you wish.
A pure C99 solution:
enum { must_be_an_array_1 = ((void *) &(arr)) == ((void *) (arr)) };
typedef char must_be_an_array_2[((void *) &(arr)) == ((void *) (arr)) ? 1 : -1];
This exploits the fact that the address of an array is the same as the address of its first member, and that an enum member must be an integral constant. If the compiler is smart enough to tell that a pointer-to-a-pointer has a distinct address, it will choke on the second statement.
We still need the first statement because otherwise a compiler with support for runtime sized arrays (e.g. gcc 4.7) will perform the address comparison at runtime and invoke undefined behaviour as the size of the runtime array is negative (e.g. under gcc the program segfaults).
Full program:
#include <strings.h>
#define CLEAN_ARRAY(arr) \
do { \
enum { must_be_an_array_1 = ((void *) &(arr)) == ((void *) (arr)) }; \
typedef char must_be_an_array_2[((void *) &(arr)) == ((void *) (arr)) ? 1 : -1]; \
bzero(arr, sizeof(arr)); \
} while (0)
int main() {
int arr[5];
CLEAN_ARRAY(arr);
int *ptr;
CLEAN_ARRAY(ptr); // error: enumerator value for ‘must_be_an_array’ is not an integer constant
return 0;
}
How to validate in c macro the argument is of ARRAY type
Use std::is_array inside of the macro. Or forget themacro and just use std::is_array.
Concerning ARRAY_SIZE,
constexpr size_t size(T const (&)[N])
{
return N;
}
As per my comment:
sizeof((x)[0]) will give an error if the type is not an "indexable" type - however, if it happens to be a pointer, it will happily take that. And also, if there is an operator[] for the type of x.
It is quite hard in C to do this, but C++ may allow some template type solutions (I don't actually know how to do that, as I've never tried to do that, or anything similar with templates).
(for C++) my current clear macro in VS2010 is:
#define CLEAR(v) do { __pragma(warning(suppress: 4127 4836)) typedef std::remove_reference< decltype(v)>::type T; static_assert( std::is_pod<T>::value || (__has_trivial_constructor(T) && __has_trivial_destructor(T)), "must not CLEAR a non-POD!" ); static_assert( !std::is_pointer<T>::value, "pointer passed to CLEAR!" ); memset(&(v), 0, sizeof(v)); } while(0)
You can make up your variant using stuff in type_traits header.
A formatted verision with explanations:
#define CLEAR(v) \
do { \
__pragma(warning(suppress: 4127 4836)) \
typedef std::remove_reference< decltype(v)>::type T; \
static_assert( \
std::is_pod<T>::value \
|| (__has_trivial_constructor(T) && __has_trivial_destructor(T)), \
"must not CLEAR a non-POD!" ); \
static_assert( !std::is_pointer<T>::value, "pointer passed to CLEAR!" ); \
memset(&(v), 0, sizeof(v)); \
} while(0)
outer do-while to make it usable like a genuine function in all places including if/else.
Remove_reference is needed so it works with lvalues, decltype alone makes int* and int*& different and is_pointer reports false for the latter.
The is_pod check is good for general, the additional condition allows struct A1 : A; case work where A is POD and A1 adds only more POD members. For is_pod purpose it's false, but to clear it makes the same sense.
is_pointer check guards the expected mistype when you get the indirection wrong on pointer or pass an address of struct in confusion. Use = NULL to clear a pointer please. ;-)
The __pragma is there to suppress L4 warnings that are issued otherwise.
As far as I can tell, nobody has yet provided a way to ensure that the argument of ARRAY_SIZE is actually an array.
<Edit>
Found Array-size macro that rejects pointers
Original answer follows:
</Edit>
The macro I use for this is:
#define ASSERT_EXPR(condition,return_value) \
(((char(*)[(condition)?1:-1])0)?(return_value):(return_value))
Principle:
0 is casted to pointer to array (with size of one (condition true) or minus one (condition false, generate error)). This null-pointer is then used as the condition of a ternary operator. Although we know, that it will always only evaluate the third operand (null-pointer means false), the second operand is also return_value -- this way the resulting type is the same as the type of return_value.
Using this, (and the IS_ARRAY from Richard J. Ross III's answer) I can define my safe ARRAY_SIZE macro as follows:
#define IS_ARRAY(arg) __builtin_choose_expr(__builtin_types_compatible_p(typeof(arg[0]) [], typeof(arg)), 1, 0)
#define ARRAY_SIZE(x) ASSERT_EXPR(IS_ARRAY(x), (sizeof(x)/sizeof((x)[0])) )
I didn't manage to get it working with Richard J. Ross III's two other IS_ARRAY variants, but that might be my (or gcc's) fault...
In C, this should work:
#define VALIDATE_ARRAY(arr) (void)(sizeof((arr)[0]))
int *a, b;
int main() {
VALIDATE_ARRAY(a);
VALIDATE_ARRAY(b);
return 0;
}
This program will fail to compile, because b is not an array. This is because b[0] is an invalid. It won't distinguish pointers from arrays - I don't think you can do that.
This form of the macro can only be used inside a function. If you want to use it outside a function, you'll have to modify it (e.g. to declare an extern array).

C++ equivalent to taking address of a constant?

I've got some code written in C (specifically targeted to gcc) that needs to also compile as C++ (g++). I've run into a construct I'm having difficulty dealing with.
There are some macros used in a lot of places which basically take the address of a constant, although they also work on non-constants. The construct winds up looking something like this:
int *iptr = (&(int){5});
What this essentially lets happen is a constant be specified, and then a pointer to that constant can be taken for use in a function that requires an int pointer, but only a constant is specified. Multiple values can also be specified inside the curley braces to construct an actual temporary array, too. And it works great.
Problem in, g++ does not like this at all, throwing
error: non-lvalue in unary `&'
Update: Looks like I can take the address of a constant in C++ by doing something like:
const int & ref = 5;
So that's the starting point for the direction I'm trying to take.
The following appears to work in both C and C++, although it only compiles under C++11, not C++03.
#ifdef __cplusplus
#define A(type,x) (&(const type &)(type)x)
#define Of(...) { __VA_ARGS__ }
#else
#define A(type,x) (&(type){x})
#define Of(...) __VA_ARGS__
#endif
Test Code:
int test(const void *ptr,int len) {
char *str = (char *)ptr;
int i;
for (i=0;i<len;i++) {
printf("%02X ",str[i]);
}
printf("\n");
return 0;
}
int main() {
test(A(int,5),4);
test(A(x,Of(5,6)),8);
int i=1,j=2;
test(A(x,Of(i,j)),8);
}
Edit: Whoops, not quite there. Doesn't work if the type is a pointer!
test(A(char *,9),4);
=>
error: invalid cast of an rvalue expression of type 'char*' to type 'const char*&'
Note: I'm abandoning this approach in favor of a different approach (compiling C code as C and linking it via C++) but will keep this answer up in case it is useful to somebody.

constexpr, static_assert, and inlining

I previously asked about function overloading based on whether the arguments are constexpr. I'm trying to work around the disappointing answer to that question to make a smarter assert function. This is roughly what I am trying to do:
inline void smart_assert (bool condition) {
if (is_constexpr (condition))
static_assert (condition, "Error!!!");
else
assert (condition);
}
Basically, the idea is that a compile-time check is always better than a run-time check if it's possible to check at compile time. However, due to things like inlining and constant folding, I can't always know whether a compile time check is possible. This means that there may be cases where assert (condition) compiles down to assert(false) and the code is just waiting for me to run it and execute that path before the I find out there is an error.
Therefore, if there were some way to check whether the condition is a constexpr (due to inlining or other optimizations), I could call static_assert when possible, and fall back on a run-time assert otherwise. Fortunately, gcc has the intrinsic __builtin_constant_p (exp), which returns true if exp is a constexpr. I don't know if other compilers have this intrinsic, but I was hoping that this would solve my problem. This is the code that I came up with:
#include <cassert>
#undef IS_CONSTEXPR
#if defined __GNUC__
#define IS_CONSTEXPR(exp) __builtin_constant_p (exp)
#else
#define IS_CONSTEXPR(exp) false
#endif
// TODO: Add other compilers
inline void smart_assert (bool const condition) {
static_assert (!IS_CONSTEXPR(condition) or condition, "Error!!!");
if (!IS_CONSTEXPR(condition))
assert (condition);
}
#undef IS_CONSTEXPR
The static_assert relies on the short circuit behavior of or. If IS_CONSTEXPR is true, then static_assert can be used, and the condition is !true or condition, which is the same as just condition. If IS_CONSTEXPR is false, then static_assert cannot be used, and the condition is !false or condition, which is just the same as true and the static_assert is ignored. If the static_assert cannot be checked because condition is not a constexpr, then I add a run-time assert to my code as a last-ditch effort. However, this does not work, thanks to not being able to use function arguments in a static_assert, even if the arguments are constexpr.
In particular, this is what happens if I try to compile with gcc:
// main.cpp
int main () {
smart_assert (false);
return 0;
}
g++ main.cpp -std=c++0x -O0
Everything is fine, compiles normally. There is no inlining with no optimization, so IS_CONSTEXPR is false and the static_assert is ignored, so I just get a run-time assert statement (that fails). However,
[david#david-desktop test]$ g++ main.cpp -std=c++0x -O1
In file included from main.cpp:1:0:
smart_assert.hpp: In function ‘void smart_assert(bool)’:
smart_assert.hpp:12:3: error: non-constant condition for static assertion
smart_assert.hpp:12:3: error: ‘condition’ is not a constant expression
As soon as I turn on any optimizations and thus potentially allow static_assert to be triggered, it fails because I cannot use function arguments in the static_assert. Is there some way to work around this (even if it means implementing my own static_assert)? I feel my C++ projects could theoretically benefit quite a bit from a smarter assert statement that catches errors as early as possible.
It doesn't seem like making smart_assert a function-like macro will solve the problem in the general case. It will obviously make it work in this simple example, but condition may have come from a function two levels up the call graph (but still becomes known to the compiler as a constexpr due to inlining), which runs into the same problem of using a function parameter in a static_assert.
This should help you start
template<typename T>
constexpr typename remove_reference<T>::type makeprval(T && t) {
return t;
}
#define isprvalconstexpr(e) noexcept(makeprval(e))
Explicit is good, implicit is bad, in general.
The programmer can always try a static_assert.
If the condition can not be evaluated at compile time, then that fails, and the programmer needs to change to assert.
You can make it easier to do that by providing a common form so that the change reduces to e.g. STATIC_ASSERT( x+x == 4 ) → DYNAMIC_ASSERT( x+x == 4 ), just a renaming.
That said, since in your case you only want an optimization of the programmer’s time if that optimization is available, i.e. since you presumably don’t care about getting the same results always with all compilers, you could always try something like …
#include <iostream>
using namespace std;
void foo( void const* ) { cout << "compile time constant" << endl; }
void foo( ... ) { cout << "hm, run time,,," << endl; }
#define CHECK( e ) cout << #e << " is "; foo( long((e)-(e)) )
int main()
{
int x = 2134;
int const y = 2134;
CHECK( x );
CHECK( y );
}
If you do, then please let us know how it panned out.
Note: the above code does produce different results with MSVC 10.0 and g++ 4.6.
Update: I wondered how the comment about how the code above works, got so many upvotes. I thought maybe he's saying something I simply don't understand. So I set down to do the OP's work, checking how the idea fared.
At this point I think that if the constexpr function thing can be be made to work with g++, then it's possible to solve the problem also for g++, otherwise, only for other compilers.
The above is as far as I got with g++ support. This works nicely (solves the OP's problem) for Visual C++, using the idea I presented. But not with g++:
#include <assert.h>
#include <iostream>
using namespace std;
#ifdef __GNUC__
namespace detail {
typedef double (&Yes)[1];
typedef double (&No)[2];
template< unsigned n >
Yes foo( char const (&)[n] );
No foo( ... );
} // namespace detail
#define CASSERT( e ) \
do { \
char a[1 + ((e)-(e))]; \
enum { isConstExpr = sizeof( detail::foo( a ) ) == sizeof( detail::Yes ) }; \
cout << "isConstExpr = " << boolalpha << !!isConstExpr << endl; \
(void)(isConstExpr? 1/!!(e) : (assert( e ), 0)); \
} while( false )
#else
namespace detail {
struct IsConstExpr
{
typedef double (&YesType)[1];
typedef double (&NoType)[2];
static YesType check( void const* );
static NoType check( ... );
};
} // namespace detail
#define CASSERT( e ) \
do { \
enum { isConstExpr = \
(sizeof( detail::IsConstExpr::check( e - e ) ) == \
sizeof( detail::IsConstExpr::YesType )) }; \
(void)(isConstExpr? 1/!!(e) : (assert( e ), 0)); \
} while( false )
#endif
int main()
{
#if defined( STATIC_TRUE )
enum { x = true };
CASSERT( x );
cout << "This should be displayed, OK." << endl;
#elif defined( STATIC_FALSE )
enum { x = false };
CASSERT( x );
cerr << "!This should not even have compiled." << endl;
#elif defined( DYNAMIC_TRUE )
bool x = true;
CASSERT( x );
cout << "This should be displayed, OK." << endl;
#elif defined( DYNAMIC_FALSE )
bool x = false;
CASSERT( x );
cout << "!Should already have asserted." << endl;
#else
#error "Hey, u must define a test case symbol."
#endif
}
Example of the problem with g++:
[D:\dev\test]
> g++ foo.cpp -Werror=div-by-zero -D DYNAMIC_FALSE
[D:\dev\test]
> a
isConstExpr = true
!Should already have asserted.
[D:\dev\test]
> _
That is, g++ reports (even via its intrinsic function, and even wrt. creating VLA or not) that a non- const` variable that it knows the value of, is constant, but then it fails to apply that knowledge for integer division, so that it then fails to produce warning.
Argh.
Update 2: Well I'm dumb: of course the macro can just add an ordinary assert to have there in any case. Since the OP is only interested in getting the static assert when it's available, which isn't for g++ in some corner cases. Problem solved, and was solved originally.
How is the answer to the other question disappointing? It implements almost exactly what you presently describe, except for the way the compiler prints the text in the diagnostic message.
The reason it needs to be done with throw is that compile-time evaluation of constexpr in a context that could be evaluated at runtime is optional. For example, the implementation could choose to let you step through the constexpr code in debugging mode.
constexpr is a weak attribute of functions (declaration specifier) that cannot change the resulting value of an expression using the function. It is a guarantee that the semantic meaning at runtime is fixed at compile time, but doesn't allow you to specify a special compile-time shortcut.
As for flagging invalid conditions, throw is a subexpression which is invalid as a constant expression, except when hidden in the unevaluated side of ?:, &&, or ||. The language guarantees that this will be flagged at compile time, even if the debugger lets you step through it at runtime, and only if the flag is really triggered.
The language gets things right here. Unfortunately that cannot be reconciled with the special diagnostic message feature of static_assert or branching on constexpr-ness.

What happens if you declare a variable inside a macro?

Suppose I have a macro defined as this:
#define FOO(x,y) \
do {
int a,b;
a = f(x);
b = g(x);
y = a+b;
} while (0)
When expanding the macro, does GCC "guarantee" any sort of uniqueness to a,b? I mean in the sense that if I use FOO in the following manner:
int a = 1, b = 2;
FOO(a,b);
After, preprocessing this will be:
int a = 1, b = 2;
do {
int a,b;
a = f(a);
b = g(b);
b = a+b;
} while (0)
Can/will the compiler distinguish between the a outside the do{} and the a inside the do? What tricks can I use to guarantee any sort of uniqueness (besides making the variables inside have a garbled name that makes it unlikely that someone else will use the same name)?
(Ideally functions would be more useful for this, but my particular circumstance doesn't permit that)
If we consider scoping of variables, it is guaranteed that a,b inside the do..while() will be different from the ones defined outside.
For your case, the a,b defined outside will not exist inside the do..while().
There are lots of things to watch out for when using MACROs.
Macros perform just string substitution. The semantic is low and the the compiler have a limited knowledge of the preprocessor (essentially #pragma which in fact is not a preprocessor keyword, and source line info).
In your case a and b are not initialized local value. Behavior is unpredictible.
Your expanded code is equivalent to the following one.
int a = 1, b = 2;
do {
int a___,b___;
a___ = f(a___);
b___ = g(b___);
b___ = a___+b___;
} while (0)
To avoid such case in c++ prefer the use of inline function or template.
If you use a c 1999 compliant compiler, you can use inline in c language.
http://en.wikipedia.org/wiki/Inline_function
In c you can make safer macro by defining longer variable and surrounding parameter by () :
#define FOO(x,y) \
do {
int FOO__a,FOO__b;
FOO__a = f(x);
FOO__b = g(x);
y = FOO__a+FOO__b + (y)*(y);
} while (0)
Note : I changed your example by adding a (y)*(y) to illustrate the case
It is also a good practice to use only once macro parameter.
This prevent side effects like that:
#define max(a,b) a>b?a:b
max(i++,--y)
Max will not return what you want.
Variables a and b are treated just as any local variables inside a local scope.
The C language guarantees that if those variables happen to have the same names as outer scope variables, the local variables will be the ones updated.
Here is an example to illustrate:
#include <stdio.h>
#define FOO(x) \
{ \
int a; \
a = x; \
printf("%d\n", a); \
}
int main()
{
int a = 1;
{
int a = 2;
printf("%d\n", a); // 2
FOO(3); // 3
printf("%d\n", a); // 2
}
printf("%d\n", a); // 1
getchar();
}
Now, of course it might be a bright idea to not name every single variable in your program "a" just because C guarantees that local variables take precedence. But technically there is nothing stopping you from it.
Btw MISRA-C bans naming like this, it require each variable no matter scope to have an unique name, for readability and maintenance reasons.
(As a sidenote, function-like macros is incredibly poor programming style and shouldn't be used. Use real functions instead, and inline them if performance is critical.)
There is no tricks other than garbling. The C and C++ preprocessors do not have the equivalent of lisp gensym or hygienic macros.
Nope, there is no guarantee of uniqueness.
Infact, your code is about to fail.
Macros are just like replacement of text.
I usually use crazy variable names if I am inside a macro, like this:
#define FOO(x,y) \
do {
int FOO_MACRO_a, FOO_MACRO_b;
FOO_MACRO_a = f(x);
FOO_MACRO_b = g(x);
y = FOO_MACRO_a + FOO_MACRO_b;
} while (0)
If you are targeting gcc and/or g++ then you can use their special macro block feature:
#define max(x, y) ({ typeof(x) a_ = (x); \
typeof(y) b_ = (y); \
(a_ > b_) ? a_ : b_ })
This allows you to create unique local variables, very much the same as writing a function.
Of course, for portability, it's not recommended. On the other hand, if you only plan to work on systems that offer gcc/g++, it will work on all of those.
Source: http://gcc.gnu.org/onlinedocs/gcc-3.0.1/cpp_3.html#SEC30
Further, with gcc / g++ you can use the -Wshadow command line option. In the event you inadvertently reuse a local variable with the same name, it will warn you. You can further use -Werror to transform those warnings in error. Now you can't compile if there is the possibility of a mixed up variable. You need to make sure to use a block, though. A do/while() as others have presented would do the job.
int a;
// code from macro;
do { int a = 5; ... } while(false);
With the combo I just described (-Wshadow + -Werror), you get an error when you do int a = 5.
You can actually make sure that regardless of what x and y are you won't have this problem by doing the following:
#define FOO(x,y) \
do\
{\
int x##y##a,x##y##b;\
x##y##a = f(x);\
x##y##b = g(x);\
y = x##y##a + x##y##b;\
} while (0)
By making sure a and b names contains x and y names you know they are different. But that's a really bad code and you probably shouldn't code like this.
Macros are textually expanded as is, modulo parameter replacement, so there's nothing the compiler can do to provide the sort of guarantee you're asking for -- as you can see in the expansion, the a parameter will refer to the inner a, not the outer one. The solution is indeed to use "garbled" names, e.g. int FOO_a, FOO_b;
In your macro that is indeed a danger and so is the possible reuse of x which is not guaranteed to be an l-value and could change by being used in the macro twice.
Even if you do need a macro, it can still be a light wrapper around an inline function, and one such that will take x and give you both f(x) and g(x) without possibly having to re-evaluate x would certainly be safe.
In your case something like:
template< typename T >
struct Foo
{
T& x;
explicit Foo(T&x_) : x(x_)
{
}
int f();
int g();
};
template<typename T>
Foo<T> makeFoo(T& x)
{
return Foo<T>(x);
}
#define FOO(x,y)
{
Foo FOO_VAR(x);
y = FOO_VAR.f() + FOO_VAR.g();
}
would be a safer way to do things. Of course if you don't need the macro at all, do away with it.