How to do metaprogramming without changing the source files?

To print lots of new lines with printf you can create a string that contains only new lines and use the width specifier to select how many you want. But you need to be careful not to print more than what's in the string.

#define new_lines "\n\n\n\n\n\n\n\n\n\n"

assert( desired_new_lines <= sizeof( new_lines ) - 1 );

printf( "%.*s", desired_new_lines, new_lines );

Replying to longtran2904 (#25524)

Wait, you can use sizeof on string? I don't even know that. I always thought you need to use something like strlen.


Replying to mrmixer (#25530)

Only on string literals.

uintptr_t size = sizeof( "abc" ) - 1;
assert( size == 3 );

char* string = "abc";
uintptr_t size = sizeof( string );
assert( size == 8 ); /* Size of the pointer. */

You can build string + size with macro:

typedef struct string_t {
    uintptr_t length;
    uint8_t* bytes;
} string_t;

#define string_l( literal ) ( string_t ) { sizeof( literal ) - 1, ( literal ) }

string_t string = string_l( "some string" );

I'm trying to have function overloading in C. The first idea is to just do what C++ does: mangling the name. But if I do that, I don't think the function's name in the error code would be correct. Are there any directives that can help me here?

I don't think there exists anything for that. If you change name, you'll have different name.

For function overloading there is another option you can do, if you use clang compiler - it has builtin support for overloading in C code with extra attribute on functions:

#define overload __attribute__((overloadable))

overload void fun(int x) { ... }
overload void fun(float x, float y) { ... }
// repeat for as many other arguments you want

Edited by Mārtiņš Možeiko on
Replying to longtran2904 (#25537)

Thanks! Did not know that.


Replying to mmozeiko (#25538)

There is also _Generic which lets you decide the logic of picking the overload:

//code from cppreference.com
#include <stdio.h>
#include <math.h>
 
// Possible implementation of the tgmath.h macro cbrt
#define cbrt(X) _Generic((X), \
              long double: cbrtl, \
                  default: cbrt,  \
                    float: cbrtf  \
)(X)
 
int main(void)
{
    double x = 8.0;
    const float y = 3.375;
    printf("cbrt(8.0) = %f\n", cbrt(x)); // selects the default cbrt
    printf("cbrtf(3.375) = %f\n", cbrt(y)); // converts const float to float,
                                            // then selects cbrtf
}