Skip to content

libc: C23 conformance for <assert.h>#2203

Open
kfv wants to merge 5 commits into
freebsd:mainfrom
kfv:libc/__STDC_VERSION_XXXX_H__
Open

libc: C23 conformance for <assert.h>#2203
kfv wants to merge 5 commits into
freebsd:mainfrom
kfv:libc/__STDC_VERSION_XXXX_H__

Conversation

@kfv
Copy link
Copy Markdown
Contributor

@kfv kfv commented May 17, 2026

  • Add __STDC_VERSION_ASSERT_H__ feature-test macro
  • Restrict static_assert macro definition to pre-C23 modes
  • Make assert variadic as per C23
  • Update assert.3 accordingly

Signed-off-by: Faraz Vahedi <kfv@kfv.io>
@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 17, 2026

Thank you for taking the time to contribute to FreeBSD!

Some of files have special handling:

Important

@concussious wants to review changes to share/man/

@clausecker
Copy link
Copy Markdown
Contributor

CC @bsdimp

Some thoughts on this one:

  • I think we can safely define assert to take the variable argument list in all modes as an extension, preventing friction when code bases are gradually extended to C23.

  • not sure what _assert is. Should we touch it at all?

  • document __STDC_VERSION_ASSERT_H__ please

  • your documentation change is somewhat obtuse. It “takes a variable argument list,” not “takes an ellipsis.” But even with that change, the average programmer will have a hard time understanding what that means. Perhaps it would be better to explain that starting with C23, the macro is set up such that expressions including the comma operator can be used, whereas in previous versions of the C standard, such expressions would cause syntax error. Give examples and explain how to work around this shortcoming in older language revisions (by using double parentheses)

  • if we chose to have assert(...) in all modes (which I recommend), document that this is supported as an extension

  • please check the output of your manpage with the mandoc command. In particular, .Fn just produces the argument typeset as a function name. It does not write “function” before the function name, so if you write

    The
    .Fn foo
    is bar
    

    you get something like “the foo is bar,” which is nonsensical. Try writing

    The
    .Fn foo
    macro is bar
    

    or something similar.

@concussious concussious requested a review from kostikbel May 17, 2026 23:02
@kfv kfv force-pushed the libc/__STDC_VERSION_XXXX_H__ branch from a75a7d4 to e67ed1a Compare May 17, 2026 23:46
@kfv
Copy link
Copy Markdown
Contributor Author

kfv commented May 18, 2026

  • I think we can safely define assert to take the variable argument list in all modes as an extension, preventing friction when code bases are gradually extended to C23.

Agreed. Done.

  • not sure what _assert is. Should we touch it at all?

Not sure if we should still keep it, but I think its sole purpose is backward compatibility as same-name functions with a leading underscore were seen as implementation internals back in early days of UNIX. I was not born back then, though, so I could be completely wrong.

  • document __STDC_VERSION_ASSERT_H__ please

Why should we document feature test macros? That's not something user needs to be concerned with.

  • your documentation change is somewhat obtuse. It “takes a variable argument list,” not “takes an ellipsis.” But even with that change, the average programmer will have a hard time understanding what that means.

It is not wrong, I believe. I've frequently seen "macros with an ellipsis parameter", "variadic macros", and similar terms—especially in the standard, proposal documents, and compiler documentation. But I understand your point, I'll take care of it shortly.

Perhaps it would be better to explain that starting with C23, the macro is set up such that expressions including the comma operator can be used, whereas in previous versions of the C standard, such expressions would cause syntax error. Give examples and explain how to work around this shortcoming in older language revisions (by using double parentheses)

Right, I'll take care of it tomorrow.

  • if we chose to have assert(...) in all modes (which I recommend), document that this is supported as an extension

Sure, I'll add a note for that.

  • please check the output of your manpage with the mandoc command. In particular, .Fn just produces the argument typeset as a function name. It does not write “function” before the function name, so if you write

    The
    .Fn foo
    is bar
    

    you get something like “the foo is bar,” which is nonsensical. Try writing

    The
    .Fn foo
    macro is bar
    

    or something similar.

I deliberately didn't use it for lines 105-107, but you're right about line 80. Sure. I'll do an update on the manpage tomorrow evening (better phrasing, new examples, etc.)

@kfv
Copy link
Copy Markdown
Contributor Author

kfv commented May 18, 2026

By the way, please accept my apologies if the branch is named libc/__STDC_VERSION_XXXX_H__. I started out adding missing feature test macros but ended up taking care of <assert.h>.

@kfv kfv closed this May 18, 2026
@kfv kfv deleted the libc/__STDC_VERSION_XXXX_H__ branch May 18, 2026 00:08
@kfv kfv restored the libc/__STDC_VERSION_XXXX_H__ branch May 18, 2026 00:09
@kfv kfv reopened this May 18, 2026
@clausecker
Copy link
Copy Markdown
Contributor

Why should we document feature test macros? That's not something user needs to be concerned with.

The macro is part of the C standard, but in retrospect I didn't add it to <stdbit.h> either, so maybe it's ok to not have it?

It is not wrong, I believe. I've frequently seen "macros with an ellipsis parameter", "variadic macros", and similar terms—especially in the standard, proposal documents, and compiler documentation. But I understand your point, I'll take care of it shortly.

The important thing is that whatever term we use is consistent within FreeBSD's documentation. Perhaps @concussious can say more here.

Looking forwards to your updates and don't worry about the branch name.

@clausecker
Copy link
Copy Markdown
Contributor

Another thing: please add to HISTORY the version in which assert() was extended to handle commas in its argument list (this should indicate 15.2 as the first version with the feature).

@kfv
Copy link
Copy Markdown
Contributor Author

kfv commented May 18, 2026

The macro is part of the C standard, but in retrospect I didn't add it to <stdbit.h> either, so maybe it's ok to not have it?

Conforming implementations must define __STDC_VERSION_XXXX_H__ macros for all headers listed in the standard, so omitting them is not acceptable, I believe. You also have it set correctly in <stdbit.h>. For more details, see the final edition of C23 Implications for C Libraries by Jens Gustedt.

In the meantime, I am working on a separate PR to address the remaining missing __STDC_VERSION_XXXX_H__ macros across the tree and will submit it within the next few hours.

As mentioned in the shared document, the macro can be defined before full conformance (e.g. as an include guard only) as long as its value is empty or a smaller number like 0. Once that header is fully conforming to C23, the value must be 202311L.

The important thing is that whatever term we use is consistent within FreeBSD's documentation. Perhaps @concussious can say more here.

You're right, it now makes complete sense to me. Fair point. Thanks.

Looking forwards to your updates and don't worry about the branch name.

Thanks, Robert.

Another thing: please add to HISTORY the version in which assert() was extended to handle commas in its argument list (this should indicate 15.2 as the first version with the feature).

Sure, will do.

@kfv
Copy link
Copy Markdown
Contributor Author

kfv commented May 18, 2026

In the meantime, I am working on a separate PR to address the remaining missing __STDC_VERSION_XXXX_H__ macros across the tree and will submit it within the next few hours.

Just opened the PR as a draft. I'll add description and mark it as ready for review once my tests complete, but happy to hear any early feedback or requests in the meantime.

@kfv kfv force-pushed the libc/__STDC_VERSION_XXXX_H__ branch from e67ed1a to 98422a1 Compare May 19, 2026 09:43
@bms
Copy link
Copy Markdown

bms commented May 19, 2026

OT: An adjacent data point to consider for assert(): if you're profiling code bases for source code complexity metric, allegedly its use bloats the SonarSource metric. as measured by clang-tidy, and this requires a specific workaround. Found because I've been doing background research to support falsifying certain other... hypotheses.

@kfv
Copy link
Copy Markdown
Contributor Author

kfv commented May 20, 2026

OT: An adjacent data point to consider for assert(): if you're profiling code bases for source code complexity metric, allegedly its use bloats the SonarSource metric. as measured by clang-tidy, and this requires a specific workaround. Found because I've been doing background research to support falsifying certain other... hypotheses.

Interesting! Thanks for the point. I'd love to hear more about your findings.

@kfv
Copy link
Copy Markdown
Contributor Author

kfv commented May 20, 2026

Addressed Robert's notes as best I could. I kept the ellipsis term but tried to clarify the macro signature description around it (I'm open to removing it altogether, but couldn't think of a better phrasing, to be honest). Let me know if you any suggestions.

Cc: @clausecker, @concussious

Copy link
Copy Markdown
Contributor

@clausecker clausecker left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

More corrections.

Is the complicated definition of assert() something Jens Gustedt cooked up?

Comment thread include/assert.h Outdated
Comment thread include/assert.h Outdated
Comment thread include/assert.h Outdated
Comment thread share/man/man3/assert.3
Comment thread share/man/man3/assert.3 Outdated
Comment thread share/man/man3/assert.3 Outdated
Comment thread share/man/man3/assert.3 Outdated
macro handles transparently:
.Dl assert((struct iovec){ buf, len }.iov_len);
.Pp
The following asserts that the size of the S structure is 16.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please use .Vn for S.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did you mean .Vt? .Vn doesn't appear to exist in mdoc(7). I used .Vt here, though .Sy would also be reasonable — happy to switch if you have a preference. By the way, I didn't fold it into a fixup since the file was untouched by my previous commits.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh sorry, I meant .Va for variable name. .Vt is for variable types, though I think you are right that it is better. Not sure in any case.

Comment thread share/man/man3/assert.3 Outdated
Comment thread share/man/man3/assert.3 Outdated
@kfv
Copy link
Copy Markdown
Contributor Author

kfv commented May 20, 2026

Is the complicated definition of assert() something Jens Gustedt cooked up?

No, Peter Sommerlad.

kfv added 3 commits May 22, 2026 16:46
Signed-off-by: Faraz Vahedi <kfv@kfv.io>
Signed-off-by: Faraz Vahedi <kfv@kfv.io>
Signed-off-by: Faraz Vahedi <kfv@kfv.io>
@kfv kfv force-pushed the libc/__STDC_VERSION_XXXX_H__ branch from c1663ec to 0a01996 Compare May 22, 2026 13:16
@clausecker
Copy link
Copy Markdown
Contributor

@kfv Please try to avoid force-pushing unless you merely do a rebase. Force pushes make it really hard to see what changes you did relatively to the previous state. It's better if you push fix-up commits; we'll squash them on commit.

@kfv
Copy link
Copy Markdown
Contributor Author

kfv commented May 22, 2026

@kfv Please try to avoid force-pushing unless you merely do a rebase. Force pushes make it really hard to see what changes you did relatively to the previous state. It's better if you push fix-up commits; we'll squash them on commit.

Understood, sure, will do.

Signed-off-by: Faraz Vahedi <kfv@kfv.io>
Copy link
Copy Markdown
Contributor

@clausecker clausecker left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this looks pretty good.
Will do some final checks if this works in C99 mode, too, and if it does, land the change set.

@bsdimp
Copy link
Copy Markdown
Member

bsdimp commented May 22, 2026

I'm almost positive _Bool will work in c99 and c89 compilation environments. Both gcc and clang have these always on. They do for other __foo things.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants