Notion: Working with variable arguments in C is weird.

Hypothesis: It might be weird because I am used to it with more....err...dynamic languages.

Solution: hit the docs and stop bitching about shit

Situation that put me in here: Trying to do a game engine is hard....

  • 4
    Do you mean variadic?
  • 6
    The real pain begins when you try to support multiplayer over network. 😄
  • 5
    About the only reason I've ever used variable argument lists in C is interfacing some sort of printf for loggers or so.

    Outside of that, real function prototypes are the usual solution, and only if that totally doesn't work, using some void pointer along with data length and format indicator, but that's already dirty.
  • 5
    @Lensflare fk, yes, variadic, sorry man, it is 5 in the morning and my brain is mush
  • 5
    @Fast-Nop ding ding ding, that is exactly what I am doing, a custom logger. This + macro programming which are in C completely new things to me are making my head spin. I'll get to it eventually through practice. For right now I have covered all different levels of logging that I could need for what I am doing, might be plenty of room to upgrade, but for right now I am content and will probably go night night
  • 4
    They start making sense when you work with them enough. I wrote several Logging engines for my own game engines back in the day... that being said I remember nothing, but it sure was cool!
  • 1
    I have a logger in my c project and tried this to match the printf syntax but quickly gave up, dont get how those arg lists work
  • 1
    @ArtOfBBQ I combined the only way I can realistically think about macros and varargs from a language that is not Lisp into something more modern. Basically, I toyed with the idea of decorators in Python, since they made me think of macros. Then in a header file (log.h) I defined the levels for the log in an enum (fatal, error and debug for now)

    I have a function declaration that takes the level, a const char for the message and the varidic arguments.

    After that for each one of the log levels, I created a macro function declaration that would "extend"?(dunno the correct word) the actual log function depending on the use casa, FLOG for fatal level ELOG etc etc.

    The syntax tripped me out:

    #define FLOG(message, ...) logger(LL_FATAL, message, ##__VA_ARGS__)

    Then on the actual log.c file I just filled in the rest from where I got the argument lists, the syntax for that is not as un-intutive as I thought and based myself on the specification for fprintf
  • 1
    @ArtOfBBQ but to be fair it was quite fucky to figure this out, specially since A) I am no C expert, and B) I have no clue what I am doing when it comes to C development. I approach it with a high level of respect.

    But understanding what can be done through macros gives me an idea as to how a lot of custom shit can be done. I even managed to create it's own assertion and detection mechanism that can even point at errors as they appear in specific files per line in which the code is showing.

    I can't say I can replicate this in other environments, safe for Lisp in which code introspection is really doable, but that is a different use case.

    C is complex, but not complicated, one just really needs to know what they are doing.
  • 0
    @AleCx04 C is very easy actually i think it's the best language and we've been going down the wrong path ever since

    but yeah i don't really like the variable argument length syntax thing, I ended up with this

    log_append("Variable i is currently: ");

    instead of
    printf("variable i is currently: %u", i);

    for me it's fine and i can focus on something else
  • 1
    @AleCx04 btw in your version you can pass __func__ and some other macros to automatically get the function or the line number where the log statement was called

    it's easy and maybe interesting for your case
  • 1
    @ArtOfBBQ The approach with your two function calls falls flat as soon as multithreading is involved - unless you also slap a mutex around them, and that becomes bulky if you have to do that in every call.

    Here's what I used for a simple logger. It just prints to stdout, or errors to stderr, and relies on a logger-static variable "verbosity" which can be set via another setter function.
Add Comment