Example of using the ## preprocessor operator - c

I know the following is a very trivial example, but how would I convert the following into a single function call that uses the preprocessor ## 'glue' operator?
void print_string(char *s)
{
printf("%s\n", s);
}
void print_num(int n)
{
printf("%d\n", n);
}
int main(void)
{
print_string("Hello");
print_num(5);
}
The only thing I can thing of (which doesn't really simplify anything) is:
#define PRINT(type) print_ ## type
PRINT(string)("Hello");
PRINT(num)(4);
Or, is there a better way to use that?

You can make the identification to be the first function argument:
#define PRINT(type, value) print_ ## type(value)
PRINT(string, "Hello");
PRINT(num, 4);
But I see no value in that over just writing printf, as someone will have to learn to write num in case of int, he might as well learn to use %d anyway:
printf("%s\n", "Hello");
printf("%d\n", 4);
Type dispatch is not possible in pre-processor - it's not aware of types. In C11 there's _Generic that allows compiler to choose different function depending on type:
#define PRINT(value) _Generic((value), \
char *: print_string, \
int: print_int)(value)
PRINT("Hello");
PRINT(4);
By overloading the macro on each argument and applying such _Generic macro on each argument it's possible to build a replacement for C++ std::cout. So a little self-promotion: that's a topic I explored in yio library that allows just to do:
yprint("Hello ", 4, "\n");

Related

Use of pasting operator `##` with types in C

Is it possible to define a macro for the C preprocessor which takes an array as argument and expands to <type of array elements>_string? For example if x in an array of integers the macro invoked with argument x should expand to int_string.
I tried with
#define TypePaste(array) typeof(array[0])##_string
but it expands to )_string.
Even using multiple levels of indirection for the ## operand the macro doesn't expand correctly.
That's not possible. At the translation phase (the preprocessing phase) where macros are expanded and tokens are concatenated, the compiler (at this point, the preprocessor) does not yet have the notion of a type and thus cannot possibly generate types.
It is not all that clear what problem you are trying to solve, but given your comment:
the macro should expand to the name of an existing function. I'd like to define a function <type>_string for every existing type and then use the macro to select the right function according to the type of the array given.
Then you could use the C11 _Generic keyword:
#include <stdio.h>
void int_string (size_t size, int array[size])
{
printf("I am %s, do stuff here.\n", __func__);
}
void float_string (size_t size, float array[size])
{
printf("I am %s, do stuff here.\n", __func__);
}
#define TypePaste(array) \
_Generic( array, \
int: int_string, \
float: float_string ) \
(sizeof(array)/sizeof(*array), array) // function parameters
int main()
{
int i_arr[5];
float f_arr[3];
TypePaste(i_arr);
TypePaste(f_arr);
}
Output:
I am int_string, do stuff here.
I am float_string, do stuff here.
Note: this assumes that the passed parameter is a local/file scope allocated array. If passing a pointer, there's no type safety and the program will fail.
C11's _Generic type selection is the "proper" way to do what you want. There are other, platform dependent solutions, tough.
If you are using gcc – you don't say so eplicitly, but you use gcc's extension typeof already – you can use gcc's statement expresions and nested functions to create a comparison function for qsort on the spot:
double a[5] = {8.4, 8.1, 9.3, 12.2, 5.2};
qsort(a, 5, sizeof(*a), ({
int cmp(const void *p, const void *q) {
const typeof(a[0]) *pp = p;
const typeof(a[0]) *qq = q;
return (*pp < *qq) ? -1 : (*pp > *qq);
}
cmp;
}));
This creates a function and returns its address. (The last statement of a compound expression is its value. The scope of the local variables is the statement expression, but a nested function is not created on the stack so its safe to return a pointer to that function.)
For primitive types, where you want to sort according to the comparison operators < and >, you can turn that into a macro:
#define COMPARE(ARRAY)({ \
int cmp(const void *p, const void *q) { \
const typeof(ARRAY[0]) *pp = p; \
const typeof(ARRAY[0]) *qq = q; \
return (*pp < *qq) ? -1 : (*pp > *qq); \
} \
cmp; \
})
qsort(a, 5, sizeof(*a), COMPARE(a));
or even:
#define SORT(ARRAY, N) \
qsort(ARRAY, N, sizeof(*ARRAY), COMPARE(ARRAY))
SORT(a, 5);
That's not Standard C, so if you need compatibility between platforms, this is out of the question.

expected expression before do. macro using do while loop

I have implemented my custom sizeof operator as below
#define my_sizeof(x) do{\
typeof(x) _a;\
(char*)(&_a + 1) - (char*)(&_a);\
}while(0)
If I compile it I get the error
test.c:26:22: error: expected expression before ‘do’
Can't figure out what I am doing wrong.
My main function is given below.
int main()
{
int a;
unsigned long long b;
double c;
printf("size of a %zd \n",my_sizeof(a));
printf("size of b %zd \n",my_sizeof(b));
printf("size of c %zd \n",my_sizeof(c));
return 0;
}
Your macro expands to a do loop. A do loop is not an expression, and does not produce a value. The compiler is telling you that you cannot use a do loop where you are trying to use one, and it is right.
There is no clean alternative in C, since you cannot declare a variable inside an expression.
This is because of the way you macro is preprocessed. The preprocessor output (which you may get using gcc -E file.c) will look like this (stripped for a variable only):
int main() {
int a;
printf("size of a %zd \n", do { typeof(a) _a; (char*)(&_a + 1) - (char*)(&_a); } while (0));
return 0;
}
which is not a correct C syntax. You could use do..while macro like that though (without an assignment or nesting it inside another function):
MY_MACRO(x);
Refer to this article for some more information.
A do/while loop can't return a value. You could instead use a GCC-style statement expression to do what you're trying:
#define my_sizeof(x) ({ \
typeof(x) _a; \
(char*)(&_a + 1) - (char*)(&_a); \
})
Clang & GCC support statement expressions for sure, I don't know about any other compilers off the top of my head.

C Macro with varargs

I am trying to write a macro which returns the smallest value of several integers. When I compile the following code, it throws an error "expected expression". I don't know what's wrong there. Could anyone point out the issues with this code?
#define SMALLEST (nums, (ret_val), ...) \
do { \
int i, val; \
va_list vl; \
va_start(vl,nums); \
(*ret_val) = va_arg(vl, int); \
for (i = 1; i < nums; i++) \
{ \
val=va_arg(vl, int); \
if ((*ret_val) > val) \
(*ret_val) = val; \
} \
va_end(vl); \
} while(0)
int main ()
{
int nums = 3;
int ret_val = 0;
SMALLEST(nums, &ret_val, 1, 2, 3);
return 0;
}
I am just curious about how to do it with Macro.
I am just curious about how to do it with Macro.
You can't. va_list is a way for a variadic function to access its arguments. What you have written is a variadic macro. They are not the same (in particular the variadic macro is still only a syntactic convenience that does not let you process individual arguments). The only way to do what you want is to call a variadic function of your own design inside the variadic macro (and then you might as well eliminate the macro).
However, if you really insist on using a variadic macro, it turns out that you are lucky that the same separator , is used in macro arguments and in array initializers, so you can try something like:
#define F(X, ...) \
do { \
int t[] = { __VA_ARGS__ }; \
for (int i = 0; i < sizeof t / sizeof t[0]; i++) \
… \
} while (0)
I don't think you can. From the gcc manual (https://gcc.gnu.org/onlinedocs/cpp/Variadic-Macros.html) the best you can do in a standard way is write __VA_ARGS__, which will expand the arguments in place (for example to pass to a function).
It then goes on to define other non-standard extensions, which you might be able to use, but wouldn't be standard.
Why not do it with a function?
The way you deal with argument lists in variadic macros is not the same as the way you deal with them in variadic functions. Instead of using va_list and its related macros, you use __VA_ARGS__.
That is pretty much the extent of it: you cannot write a macro that processes variadic list from the beginning to the end; you are limited to passing the arguments through to a variadic function, which performs the actual processing.
Note: Your implementation is incorrect, too: you should be using va_start(vl,ret_val) instead of va_start(vl,nums), because you are supposed to pass the last argument before ... to va_start.
If I were to rewrite this as a function, though, I would drop the ret_val pointer, and make a function that returns a value the regular way.
It makes no sense to do that with macro. That's what functions are for.
You get an error because the SMALLEST symbol in your main function gets replaced by the whole body of the function you've defined. AFAIK you can't define a function inside another function in C.
Is there any particular reason why you want to use a macro here? You seem to be confusing macro syntax and standard syntax (the reason for your error).
You should use a function to achieve this - this is what a function is for. The following code should get you what you want:
int Smallest( int iNumberOfIntegers, ... )
{
va_list args = NULL;
int i = 0;
int iSmallestValue = 0;
int iCurrentValue = 0;
va_start( args, iNumberOfIntegers );
iSmallestValue = va_arg( args, int );
for(i = 0; i < iNumberOfIntegers - 1; i++)
{
iCurrentValue = va_arg( args, int );
if(iSmallestValue > iCurrentValue)
{
iSmallestValue = iCurrentValue;
}
}
return iSmallestValue;
}
Of note, you you need to pass the size of the variadic argument if you are going to loop over it in this manner. This is not necessary in format strings because the compiler can infer the number from the format string specifiers.
We subtract 1 from the loop to account for a 0 offset.
Edit: And, as others have said, you can't use a variadic macro in the way you were trying.

static_if in C99's preprocessor

Is it possible to implement static_if in C99?
#define STATIC_IF(COND, ...) \
if (COND) MACRO1(__VA_ARGS__); \
else MACRO2(__VA_ARGS__);
How can I properly implement STATIC_IF(…) in here? Depending on COND the arguments either should be passed to MACRO1 or MACRO2, but the arguments for both macros look differently. COND is statically testable, something like sizeof (…) > 42.
#if COND then #define STATIC_IF MACRO1 … wouldn't work for my use case.
I cannot use compiler specific solutions.
In your specific case (if I understand your comments correctly), yes, you can do this.
You can't pass sizeof to anything in the preprocessor because the preprocessor runs before type information is available. Luckily for you, you don't need sizeof to count the number of arguments in a statically-written list (X-Y alert!), so this is no obstacle.
Here's one possible implementation using the Order macro library:
#include <stdio.h>
#include <order/interpreter.h>
void oneArg(int a) {
printf("one arg: %d\n", a);
}
void twoArgs(int a, int b) {
printf("two args: %d %d\n", a, b);
}
void threeArgs(int a, int b, int c) {
printf("three args: %d %d %d\n", a, b, c);
}
#define ORDER_PP_DEF_8function_list \
ORDER_PP_CONST(("unused") \
(oneArg) \
(twoArgs) \
(threeArgs))
#define SelectFunction(...) ORDER_PP ( \
8seq_at(8tuple_size(8((__VA_ARGS__))), 8function_list) \
)
#define Overloaded(...) SelectFunction(__VA_ARGS__)(__VA_ARGS__)
int main(void) {
Overloaded(42);
Overloaded(42, 47);
Overloaded(42, 47, 64);
return 0;
}
(This simple case indexes a list by the number of arguments - probably not exactly what you want to do, but enough to get the idea. Order does provide a full range of complex, nonevaluating control structures - if, cond, match, etc. - for more complex decision-making.)
Order is pretty heavyweight: I assume you can do something similar with the much lighter and more realistically-portable P99 (not familiar with it). Order works very well with GCC and adequately well with Clang (Clang will choke on deep recursion or long loops); it is standard, but not all compilers are.
This is not possible, because a condition like sizeof(something)>42 is not static for the preprocessor. The preprocessor is purely textual (in principle, except for arithmetic). It does not know about C or types.
Notice that expression of the condition in #if is severely constrained.
However, you could use build tricks. For instance, you might have a standalone program like
// generate-sizeof.c
#include <stdio.h>
#include "foo-header.h"
int main(int argc, char**argv) {
const char* headername = NULL;
if (argc<2)
{ fprintf(stderr, "%s: missing header name\n", argv[0]);
exit(EXIT_FAILURE); };
headername = argv[1];
FILE *fh = fopen(headername, "w");
if (!fh) { perror(headername); exit(EXIT_FAILURE); };
fprintf(fp, "// generated file %s\n", headername);
fprintf(fp, "#define SIZEOF_charptr %d\n", (int) sizeof(char*));
fprintf(fp, "#define SIZEOF_Foo %d\n", (int) sizeof(Foo));
fclose (fp);
}
then have a rule like
generated-sizes.h : generate-sizeof foo-header.h
./generate-sizeof generated-sizes.h
in your Makefile etc etc...
So your build machinery will generate the appropriate headers.
Things become much tricker if you want to cross-compile!
Then you might have an #include "generated-sizes.h" in your header, and later code
#if SIZEOF_Foo > 42
#error cannot have such big Foo
#endif
I don't think so, not in the sense you mean.
But: I would just go ahead, and trust that an optimizing compiler notices that the condition is always true (or false) and does the right thing, i.e. optimizes out the test.
You might need to force some optimization to provoke the compiler into doing this.
If you can remove the restriction of having to stick to C99, there is a better solution to this problem built-in to the language since C11:
#include <stdio.h>
void f1(float x, double y, float * z) {
printf("inside f1\n");
}
void f2(int x, _Bool * y) {
printf("inside f2\n");
}
#define STATIC_IF(COND, ...) _Generic(&(int[(!!(COND))+1]){ 0 }, \
int(*)[2]: f1, \
int(*)[1]: f2) \
(__VA_ARGS__)
int main(void) {
float fl;
_Bool b;
STATIC_IF(sizeof(double) > 4, 0.0f, 1.0, &fl);
STATIC_IF(sizeof(double) > 128, 16, &b);
}
The _Generic operator performs a compile-time selection based on a type. Since it selects based on a type, it's also the only language-level expression that can accept conflicting types of "argument", since its very purpose is to resolve a value of the right type based on inputs.
This means you can easily use it to choose between your two functions with incompatible signatures, because it will completely ignore the type of the one that isn't chosen by matching the input; the arguments (applied to whichever function _Generic returns) will only be checked against the successful match.
Although _Generic is designed to dispatch on types, not values, any integer constant expression can be "turned into" a type by using it as the size of an array. So in the above macro we create an anonymous array (n.b. this is not a VLA), of count either 2 (for true) or 1 (for false) and dispatch against the type of the pointer to that array in order to resolve which of the two incompatible functions to use.
This will certainly reduce to nothing at runtime, since not only is the condition static, but the alternative "execution path" wouldn't even type check and thus can't have code generated for it in the first place.

Returning a Character String from #define Function

I know you can return a character string from a normal function in C as in this code
#include <stdio.h>
char* returnstring(char *pointer) {
pointer="dog";
return pointer;
}
int main(void)
{
char *dog = NULL;
printf("%s\n", returnstring(dog));
}
However, I can't find a way to be able to return character strings in #define functions, as in this code
#include <stdio.h>
#define returnstring(pointer) { \
pointer="dog"; \
return pointer; \
}
int main(void)
{
char *dog = NULL;
printf("%s\n", returnstring(dog));
}
I know that there are workarounds(like using the first program). I just want to know if it is possible
Thinking about a "#define function" is, IMO, the wrong way to approach this.
#define is a blunt instrument which amounts to a text find/replace. It knows little to nothing about C++ as a language, and the replace is done before any of your real code is even looked at.
What you have written isn't a function in its own right, it is a piece of text that looks like one, and it put in where you have written the alias.
If you want to #define what you just did, that's fine (I didn't check your example specifically, but in general, using #define for a function call and substituting the arguments is possible), but think twice before doing so unless you have an amazing reason. And then think again until you decide not to do it.
You can't "return" from a macro. Your best (ugh... arguably the "best", but anyway) bet is to formulate your macro in such a way that it evaluates to the expression you want to be the result. For example:
#define returnstring(ptr) ((ptr) = "hello world")
const char *p;
printf("%s\n", returnstring(p));
If you have multiple expression statements, you can separate them using the horrible comma operator:
#define even_more_dangerous(ptr) (foo(), bar(), (ptr) = "hello world")
If you are using GCC or a compatible compiler, you can also take advantage of a GNU extension called "statement expressions" so as to embed whole (non-expression) statements into your macro:
#define this_should_be_a_function(ptr) ({ \
if (foo) { \
bar(); \
} else { \
for (int i = 0; i < baz(); i++) { \
quirk(); \
} \
} \
ptr[0]; // last statement must be an expression statement \
})
But if you get to this point, you could really just write a proper function as well.
You don't return anything from a #defined macro. Roughly speaking, the C preprocessor replaces the macro call with the text of the macro body, with arguments textually substituted into their positions. If you want a macro to assign a pointer to "dog" and evaluate to the pointer, you can do this:
#define dogpointer(p) ((p)="dog")
The thing is returnstring as a macro does not do what it says; it also assigns the value to the parameter. The function does as it says, even if it (somewhat oddly) uses its parameter as a temporary variable.
The function is equivalent to:
char* returnstring(char *ignored) {
return "dog";
}
The function macro is much the same as:
#define returnstring(pointer) pointer = "dog"
Which begs the question, why not call it assign_string?
Or why not just have:
#define dogString "dog"
And write:
int main(void)
{
char *dog = NULL;
printf("%s\n", dog = dogString);
}
The function for assignString is:
char* assignstring(char **target{
*target= "dog";
return *target;
}
You can then have a macro:
assign_string_macro(pointer) assignstring(&pointer)
Ultimately if you want to "return character strings in #define functions", then all you need is:
#define returnstring(ignored) "dog"

Resources