20 pointsby jandeboevrie6 hours ago2 comments
  • Crisco15 minutes ago
    I recently got into GBA development and was planning on figuring out how to do this exact thing today, so I’m happy to have found this article.

    Anecdotally I’ve found that GBA and embedded development is very fun, especially since I’ve set the rule for myself to never use LLM generated code. I don’t really have the ability to not interact with LLMs at work, so being able to return to how things used to be and feel the satisfaction of building a project from scratch has enhanced my interest and excitement for personal projects.

  • scraft3 hours ago
    Small defensive suggestion: I’d usually define both the enabled and disabled versions as statement-like macros:

      #ifdef MGBALOG
      #define mgbalog(level, format, ...) \
          do { _mgbalog(level, format, ##__VA_ARGS__); } while (0)
      #else
      #define mgbalog(level, format, ...) \
          do { } while (0)
      #endif
    
    For the exact usage shown here, "mgbalog(...);" will mostly work with the empty replacement-list version, since it just leaves a bare ";". So this is not a guaranteed bug.

    The reason I prefer the "do { } while (0)" form is that it keeps the macro structurally equivalent to a single statement in both debug and release builds. With the empty disabled macro, this:

      if (failed)
          mgbalog(ERROR, "failed");
    
    becomes:

      if (failed)
          ;
    
    That is valid C, but it can trigger empty-body / suspicious-semicolon warnings, for example GCC’s "-Wempty-body", which matters if the project builds with "-Wextra" or warnings-as-errors.

    It also means the enabled case is already set up correctly if the macro later grows beyond a single function call. For example, if you later add another statement to the macro:

      #define LOG(x) printf("log\n"); printf("%s\n", x)
    
      if (failed)
          LOG("failed");
      else
          recover();
    
    then the expansion breaks because the "else" no longer attaches to the intended "if".

    So in this specific case the empty macro is probably fine for ordinary "mgbalog(...);" calls, but wrapping both versions in "do { } while (0)" is the more conventional and future-proof C macro shape.