Hello Alejandro.

Alejandro Colomar via Mutt-dev wrote in
 <aefqanH_-tiRgHxI@devuan>:
 |On 2026-04-21T16:55:51+0200, Steffen Nurpmeso wrote:
 |[...]
 |> No no, it was broken.  It could not evaluate the same expressions
 |> as the C++ variant could.  Maybe it was a compiler error, then.
 |> Note the IANA TZ project also did it like so:
 |> 
 |>     * private.h (static_assert): New macro, defined for pre-C23 compilers\
 ...
 |>   +#if __STDC_VERSION__ < 202311
 |>   +# define static_assert(cond) extern int static_assert_check[(cond) \
 |>   ? 1 : -1]
 |>   +#endif
 |> 
 |> (I am now not reading exact ISO C definitions to find reasons why
 |> the C11 variant was borked.  But it was once i tested.)
 |
 |Ahhh, now I see what your problem was.  The problem wasn't
 |static_assert(3) in C.  The problem was that integer constant
 |expressions were significantly more strict in C11, and C23 has allowed
 |compilers to turn some code into constant expressions in certain cases.
 |
 |I guess this is another good reason to use C23.

Or you use C89/C++98 with the simple pseudo typedef that i (and
many other people with similar ones) use for static assertions
for many many years, eg

  # define su_CTA(T,M) su__CTA_1(T, su_FILE, __LINE__)
  # define su_LCTA(T,M) su__LCTA_1(T, su_FILE, __LINE__)
  
  # define su__CTA_1(T,F,L) su__CTA_2(T, F, L)
  # define su__CTA_2(T,F,L) typedef char ASSERTION_failed_file_ ## F ## _line_ 
## L[(T) ? 1 : -1]
  # define su__LCTA_1(T,F,L) su__LCTA_2(T, F, L)
  # define su__LCTA_2(T,F,L) \
  do{\
          typedef char ASSERT_failed_file_ ## F ## _line_ ## L[(T) ? 1 : -1];\
          ASSERT_failed_file_ ## F ## _line_ ## L su____i_am_unused__;\
          su_UNUSED(su____i_am_unused__);\
  }while(0)

Yes i use static_assert() in C23+.  But i actually see no
improvement (there is actually none for me, the above "just works"
(tm)), *and* i am in doubt, because ISO C11 was unusable, C17
was unusable, but with C23 it now works.  It should never have
entered the standard until it was usable.  I am not sitting in
an almost 700 page standard (C-2011) with its "1000" undefined or
incompletely defined or so conditions, nor am i keen for this.
This is in parts where Mr. Ken Thompson picked me up.

 ...
 |>|that the macro expands internally T*, which would expand as int[4]*,
 |>|which is a syntax error.  But with typeof(), you have typeof(int[4])*,
 |>|which is correct.
 |> 
 |> I btw still prefer typedef for for example the handler (and
 |> anything prototype-ish) of signal(3) and such.  I just seem to be
 |> incapable to perform proper views at this otherwise (like the
 |> prototype shown in "man 3 signal" on Linux).
 |
 |There's signal(3posix) and signal(2).  There's no signal(3) --although
 |if you run `man 3 signal`, you'll get signal(3posix)--.
 |
 |Here's the SYNOPSIS from POSIX:
 ...
 |      void (*signal(int sig, void (*func)(int)))(int);
 |
 |And here's the one from the Linux man-pages project:
 |
 | SYNOPSIS
 |      #include <signal.h>
 |
 |      typedef typeof(void (int))  *sighandler_t;
 |
 |      sighandler_t signal(int signum, sighandler_t handler);
 |
 |The latter still uses typeof() --even if it also uses typedef-- for
 |reasons similar to malloc_T().  If we didn't use typeof() in that
 |typedef definition, it would become quite unreadable.

I have a hard time even understanding the above.  void(int), that
is a nerd horror show.  :-)

 |[...]
 |> I meant "warnings yes, but no errors".  It is sometimes at least
 |> hard enough to see the "xy is reported only once" for some
 |> warnings.  I let the compilation go one, and then crawl the (tmux;
 |> or output redirection, or what) history along.
 |> I mean sure, if you have a plethora of builds and only get
 |> a notification email, having hard errors seems the better way.
 |> But i only develop locally, and have some (by far not enough, and
 |> most younger than 2022) VMs.
 |
 |Since make(1) builds step by step, I don't see a problem in building
 |until the first error, fix a few things, and then continue the build,
 |until everything works.  I don't like navigating a sea of warnings.

Make step-by-step?  How that?  But i can hardly believe a big
project can do it like that, say a Linux kernel build?

 |>|>|If you write this malloc_T() in a library once, and then use it
 |>|>|everywhere, you shouldn't worry too much about it having too much
 |>|>|typeof magic.
 |>|> 
 |>|> Yes.  Kernel, too, and i had just seen the commit that made it
 |>|> simpler to use for the generic "bin".  (By sheer chance.)
 |>|
 |>|That commit from Torvalds was horrible.
 |>|That macro is a massive foot-gun.
 |>|<https://lore.kernel.org/lkml/abhGS0n_RsUG97Ni@devuan/>.
 |> 
 |> I remembered now that i came via
 |>   https://lwn.net/Articles/1057769/
 |> to
 |>   https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/comm\
 |>   it/?id=bdc5071d7f7b
 |> and especially
 |>   https://lwn.net/Articles/1058664/
 |> pointed to several fixes of that, like
 |>   https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/comm\
 |>   it/?id=e19e1b480ac7
 |> In this hindsight it seems hard to understand that making it
 |> "completely cool" aka "fool proof" was not an option.
 |
 |I think it's a combination of
 |
 |-  They didn't realize it would be so dangerous.
 |-  Lack of communication.
 |
 |I'm more concerned about the fact that it hasn't been fixed.  And I'm
 |even more worried by the fact that the kernel-hardening maintainer is
 |worried of annoying Torvalds with a fix, so they prefer not fixing it at
 |all.  That doesn't seem healthy.
 |
 |> (*But*, then again, i remember compiler errors with MACRO(x,y,)
 |> syntax, and i even remember being surprised a couple of years ago
 |> that MACRO(x,y, ), ie with space, worked!
 |
 |Could you please point to those?  I'd be interested in investigating
 |that.  I don't see reasons why that should be any different.  I'd like
 |to see a small reproducer piece of code.

Only just like i said.  (Ie, some macro with (xy,) and one with
(xy, ).)  But no, i cannot, other than that.  I think we are, at
least in parts, talking times when there was not even __VA_ARGS__,
widely spread at least; we did not use such preprocessor things
until .. actually i am still very careful with that, my pam_xdg.c
(that is *mine*, not the other one(s)) for example still says

  pam_xdg.c: *@ - Requires C preprocessor with __VA_ARGS__ support!

and that is hammer!, you know -- even va_list was not everywhere
at times, at least potentially!

--steffen
|
|Der Kragenbaer,                The moon bear,
|der holt sich munter           he cheerfully and one by one
|einen nach dem anderen runter  wa.ks himself off
|(By Robert Gernhardt)

Reply via email to