Simple tuple operation - c-preprocessor

Say I have a tuple:
#define T (a, b)
How can I extract first and second element of the tuple in gcc, without use of any external libraries?

I found one way of doing this. I'm not sure if this would work in anything else than gcc.
#define first_(x, y) x
#define first(t) first_ t
#define second_(x, y) y
#define second(t) second_ t
#define T (a, b)
first(T) // expands to a
second(T) // expands to b

Related

Macros #if directive with non integer definition

I'm having a 20yo legacy code (pure C) which defines:
#define X float
before first function and before another function:
#undefine X
#define X double
I'm writing a code which is supposed to work with both definitions (and it'll be copied into both functions automatically). But it's impossible to make such code in a few cases. For these cases I need to detect if my X is float or double and use #if #else #endif.
The #if (X == float) is resolved as 0 == 0 and won't work.
In theory I can grab into legacy code and modify these definition to make my life easier, but I wonder if there is any macro magic which would allow me to workaround this without touching the legacy? Something with conversion X to string may be? Any ideas?
Concatenate with prefix that expands to something you can control.
#define PREFIX_float 0
#define PREFIX_double 1
#define CONCAT(a, b) a##b
#define XCONCAT(a, b) CONCAT(a, b)
#if XCONCAT(PREFIX_, X) == PREFIX_float

How to control C Macro Precedence

#define VAL1CHK 20
#define NUM 1
#define JOIN(A,B,C) A##B##C
int x = JOIN(VAL,NUM,CHK);
With above code my expectation was
int x = 20;
But i get compilation error as macro expands to
int x = VALNUMCHK; // Which is undefined
How to make it so that NUM is replaced first and the JOIN is used?
You can redirect the JOIN operation to another macro, which then does the actual pasting, in order to enforce expansion of its arguments:
#define VAL1CHK 20
#define NUM 1
#define JOIN1(A, B, C) A##B##C
#define JOIN(A, B, C) JOIN1(A, B, C)
int x = JOIN(VAL,NUM,CHK);
This technique is often used with the pasting and stringification operators in macros.

x-macro conditional error - number comparison

I would like to generate compile time error for X-macro for all X(a, b) where a > b
/* X(a, b) */
#define LIST \
X(10, 20) \
X(5, 20) \
X(30, 20) \
X(1, 20)
So, generate error for X(30, 20)
Is this possible in C?
EDIT: example usage
For me, left number is for example sizeof of some large struct and right number is fixed space to store this struct. If the struct is bigger then available space, I need compiler to generate error.
//e.g.
X(sizeof(struct conf), 2*PAGE)
Yes, here's a proof of concept:
#pragma push_macro("X")
#undef X
#define X(a,b) typedef int x[(a>b)?-1:1];
LIST
#pragma pop_macro("X")
So, we define X to define a type of array of ints, with either -1 or 1, depending whether a is greater than b. If it is, the array of -1 elements will cause an error.
If using C11, the typedef line can be done using static_assert(a<=b) from assert.h
It is possible in C11 by using the _Static_assert keyword:
#define X( a , b ) _Static_assert( a <= b , "Error!" )
Note that expressions a and b must be constant.

C Macro to remove duplicates in list of arguments

I wonder if it is possible to build a gnu C macro which expands to a list of tokens (integer numbers) which are the arguments of the macro without duplicates. The number of arguments could be assumed fixed (for the moment). I.e. I want something like:
#define MAC(a,b,c) ???
which expands e.g.
MAC(1,2,1)
to 1,2.
The arguments are not sorted and the result does not have to be.
Based on the proposal below I built an example which does essentially what I want using the p99 includes:
#include <p99/p99_if.h>
#include <p99/p99_paste.h>
#define MAC2(a,b) double P99_PASTE2(myvar_, a) P99_IF_EQ(a,b)()(; double P99_PASTE2(myvar_, b))
#define MAC3(a,b,c) double P99_PASTE2(myvar_, a) P99_IF_EQ(a,b)()(; double P99_PASTE2(myvar_, b)) P99_IF_EQ(a,c)()(P99_IF_EQ(b,c)()(; double P99_PASTE2(myvar_, c)) )
MAC2(1,2);
MAC2(3,3);
MAC3(1,2,3);
MAC3(10,10,1);
If your arguments are always small decimal numbers as in your example, you could get away with what I provide in P99. It has macros like P99_IF_EQ that you could use as
#define MAC(A,B) unsigned P99_PASTE2(myvar_, A) P99_IF_EQ(A,B)()(; unsigned P99(unsigned P99_PASTE2(myvar_, B))
MAC(1,2); // -> myvar_1 and myvar_2
MAC(3,3); // -> myvar_3
to only expand the declaration for B if it is not equal to A. Obviously for three different arguments this already becomes a bit tedious, but would be doable.

C Macro for minimum of two numbers

I want to make a simple macro with #define for returning the smaller of two numbers.
How can i do this in C ? Suggest some ideas, and see if you can make it more obfuscated too.
Typically:
#define min(a, b) (((a) < (b)) ? (a) : (b))
Be warned this evaluates the minimum twice, which was the reason for disaster in a recent question.
But why would you want to obfuscate it?
This one stores the result in a variable, and only evaluates each argument once. It's basically a poor-mans inline function + declaration:
#define min(t, x, a, b) \
t x; \
{ \
t _this_is_a_unique_name_dont_use_it_plz_0_ = a; \
t _this_is_a_unique_name_dont_use_it_plz_1_ = b; \
x = _this_is_a_unique_name_dont_use_it_plz_0_ < \
_this_is_a_unique_name_dont_use_it_plz_1_ ? \
_this_is_a_unique_name_dont_use_it_plz_0_ : \
_this_is_a_unique_name_dont_use_it_plz_1_ ; \
}
Use it like:
min(int, x, 3, 4)
/* x is an int, equal to 3
Just like doing:
int x = min(3, 4);
Without double evaluation.
*/
And, just for the hell of it, a GNU C example:
#define MAX(a,b) ({ \
typeof(a) _a_temp_; \
typeof(b) _b_temp_; \
_a_temp_ = (a); \
_b_temp_ = (b); \
_a_temp_ = _a_temp_ < _b_temp_ ? _b_temp_ : _a_temp_; \
})
It's not obfuscated, but I think this works for any type, in any context, on (almost, see comments) any arguments, etc; please correct if you can think of any counterexamples.
Sure, you can use a #define for this, but why would you want to? The problem with using #define, even with parentheses, is that you get unexpected results with code like this (okay, you wouldn't actually do this, but it illustrates the problem).
int result = min(a++, b++);
If you're using C++ not C, surely better to use an inline function, which (i) avoids evaluating the parameters more than once, and (ii) is type safe (you can even provide versions taking other types of value, like unsigned, double or string).
inline int min(int a, int b) { return (a < b) ? a : b; }
I think this method is rather cute:
#define min(a, b) (((a) + (b) - fabs((a) - (b))) * 0.5)
I want to make a simple macro with #define for returning the smaller of two numbers.
I wanted to add a solution when the numbers are floating point.
Consider when the numbers are floating point numbers and one of the numbers is not-a-number. Then the result of a < b is always false regardless of the value of the other number.
// the result is `b` when either a or b is NaN
#define min(a, b) (((a) < (b)) ? (a) : (b))
It can be desirable that the result is as below where "NaN arguments are treated as missing data". C11 Footnote #242
a NaN | b NaN | a < b | min
-------+---------+---------+---------------
No | No | No | b
No | No | Yes | a
No | Yes | . | a
Yes | No | . | b
Yes | Yes | . | either a or b
To do so with a macro in C would simple wrap the fmin() function which supprts the above table. Of course code should normally used the fmin() function directly.
#include <math.h>
#define my_fmin(a, b) (fmin((a), (b))
Note that fmin(0.0, -0.0) may return 0.0 or -0.0. They both have equal value.
If I were just trying to lightly obfuscate this I would probably go with something like:
#define min(a,b) ((a) + ((b) < (a) ? (b) - (a) : 0))
I think Doynax's solution is pretty cute, too. Usual reservations for both about macro arguments being evaluated more than once.
For slightly obfuscated, try this:
#define MIN(a,b) ((((a)-(b))&0x80000000) >> 31)? (a) : (b)
Basically, it subtracts them, and looks at the sign-bit as a 1-or-0.
If the subtraction results in a negative number, the first parameter is smaller.

Resources