News for hackers. Stuff that matters.
Re:Type-Safe Printf for C by tinkersleep on Sunday December 12, 2021 @05:47AM (#29528572)
Probably the 1e6th approach, but anyway, I also wanted to play with this myself: here's a _Generic and macro based approach to get printf type-safe in C. It needs C11, and uses some gcc extensions.
Re:Type-Safe Printf for C by marcodiego on Tuesday December 14, 2021 @02:11PM (#29555961)
I, a few times, got reasonably far implementing a generic, type-safe, variadic, macro-based and using _Generic "print" for C.

I copied some examples of how to implement variadic macros, and expanded on that for C basic types. It mostly worked, you'll always have difficulty for corner cases like separating pointers and arrays, but it worked well for the basic C types.

I gave up for a few reasons:

  - I wanted a form to register new types, so it could work for user-defined types;

  - the C pre-processor knows nothing about lists that can be expanded multiple times;

  - variadic C macros are ugly hacks.
Maybe one day I'll get back to it and publish it.

The interesting part is that _Generic combined with macros allows some very interesting tools for implementing primitive forms of polymorphism. Actually, if the C pre-processor supported lists, it would be possible to implement RTTI in C.

Re:Type-Safe Printf for C by tinkersleep on Tuesday December 14, 2021 @03:14PM (#29556903)
> - I wanted a form to register new types, so it could work for user-defined types;

Yes, I had the same urge. You can easily fall into the trap of too many features on the list. I settled on keeping user types out: you can always write a stringify() and pass that to the printf. Not the same, I know. But a more finite project.

> - the C pre-processor knows nothing about lists that can be expanded multiple times;

Yeah, that's a hack. Look at the 'VA_EXP()' macros in include/va_print/base.h. Ugly. Incomprehensible.

> - variadic C macros are ugly hacks.

Absolutely. But I think there is no other way in C.

> Actually, if the C pre-processor supported lists, it would be possible to implement RTTI in C.

I couldn't resist to put in '%t' which prints the C type of the argument...

Re:Type-Safe Printf for C by 95014_refugee on Tuesday December 14, 2021 @06:21PM (#29559540)
__attribute__((overloadable)) is also worth looking at...
Re:Type-Safe Printf for C by marcodiego on Wednesday December 15, 2021 @06:25AM (#29564490)
Hm… interesting… it would be good if GCC supported it too.
Re:Type-Safe Printf for C by bumblebritches5 on Tuesday December 14, 2021 @02:54PM (#29556624)
> - I wanted a form to register new types, so it could work for user-defined types;

> - the C pre-processor knows nothing about lists that can be expanded multiple times;

I'm actually working on both features as Clang extensions.

#repeat, a preprocessor directive to loop, can be combined with _Pragma(push_macro/pop_macro) to create lists by redefining a macro.

and currently #increment, though I think I want to expand on this so that other macros can be redefined more easily to create lists via push/pop macro.

The reason push_macro/pop_macro pragmas can't work, is the macro has to be undefined and redefined, and the value then pushed onto a stack in the compiler.

and you can't redefine a macro in the body of another macro directly.

so I've been thinking about maybe a _Pragma(redefine_macro(MacroToRedefine, NewValueForRedefinedMacro))

but I don't want it to be limited to the _Pragma area of the compiler, I want it to be eventually standardized.

I've been talking to a friend at WG14 who suggested making it a "Preprocessor Expression, like `__has_c_attribute` and `defined()`

So that's the area I've been working on recently for the Increment/Redefine PE lately.

Re:Type-Safe Printf for C by marcodiego on Tuesday December 14, 2021 @03:30PM (#29557146)
I spent a long time thinking about this. My conclusion is that the simplest way to achieve this, at least in GCC, is to create a #copy directive that allows a macro, together with its stack, to be copied to another. GCC already allows stack expansion with push and pop but it can only be expanded once; the #copy directive would fix that.

If you get anything close to that working, that would be a godsend. It is the last remaining piece of the puzzle for me to implement complete RTTI in C. It would certainly help to minimize glib boiler plate code too.

I'd really like it to be part of c2x, but I think it is too late now. If it is implemented by either GCC or Clang, the remaining other would certainly it too since it is too useful. So getting it to work in any of these would be good enough for me.

How can I track/follow your progress?

Re:Type-Safe Printf for C by tinkersleep on Tuesday December 14, 2021 @03:47PM (#29557434)
There is __VA_OPT__ in C++2a, which handles recursion termination in macro expansion. This will probably be in future C, too, right?

And if there was also __EVAL__ to force the macro preprocessor into another evaluation level, you could write recursive macros quite easily, e.g., to wrap every argument into a function call:

    #define EACH(f,x,...) f(x) __VA_OPT__(, __EVAL__(EACH(f, __VA_ARGS__)))
This would make the macro magic for this library trivial: you could process lists recursively.

Edit: added missing paren

Re:Type-Safe Printf for C by kzrdude on Tuesday December 14, 2021 @04:58PM (#29558538)
Do you have a usage example? One early in thee readme maybe. Seeing is believing