{
  "id": 14733918,
  "title": "My C23 Conventions",
  "url": "https://urgent.news/2026/10/15/my-c23-conventions",
  "topic": "tech",
  "section": "Tech",
  "published": "2026-10-15T15:32:15.000Z",
  "source": {
    "name": "Lobsters",
    "slug": "lobsters",
    "url": "https://abner.page/post/c23-conventions-1/"
  },
  "original_language": "en",
  "account": "In the latest installment of my exploration into modern C as of 2026, I've discovered three new conventions that have significantly improved my coding practices. The first of these is centered around the [[nodiscard]] keyword. When rendering app windows or panels, it's crucial that the caller captures the rendered rectangle for subsequent processing. This simple requirement has made [[nodiscard]] an indispensable tool for catching business logic bugs. However, there are instances where a drawn element has no use for the resulting rect. Previously, I would use an UNUSED() macro to suppress the warning, but now I've replaced it with [[maybe_unused]]. This change has improved my code's readability and eliminated the need for the macro altogether.\n\nAnother convention I've embraced is the use of [[maybe_unused]] for marking variables that are intentionally unused. This practice has made my code cleaner and more concise, as I no longer need to maintain a separate macro for marking unused variables. Additionally, I've noticed that many routines return different types marked with [[nodiscard]]. In these cases, it makes sense to forgo a specific macro and simply use [[maybe_unused]]. This approach has streamlined my codebase and reduced the need for custom macros.\n\nOne surprising revelation in modern C is the behavior of union members. Previously, I assumed that all union members would be zeroed, but this is not always the case. In C23, only the time_t member is guaranteed to be zeroed. This change has introduced some uncertainty into my code, as I can no longer rely on the {0} initializer to clear all union members. According to Jens Gustedt, specifying the underlying integer type for enumeration constants is a better practice. This advice has prompted me to be more cautious when defining enums and to avoid potential surprises due to unexpected type sizes.",
  "summary": null,
  "key_points": [],
  "editors_take": null,
  "illustration": null,
  "coverage": {
    "outlets": 1,
    "also_reported_by": []
  },
  "ai_generated": true,
  "disclaimer": "Summaries, key points and the editor’s take are written by software from other outlets’ reporting and may contain errors — always check the linked original."
}