Skip to content

CWG3142 [cpp.predefined] Binary integer literal and digit separators for __LINE__ #826

Description

@frederick-vs-ja

Full name of submitter (unless configured in github; will be published with the issue): Jiang An

Reference (section label): [cpp.predefined]

Link to reflector thread (if any):

Issue description:

Discovered in cplusplus/draft#8584 (comment).

It's possible to static_assert that __LINE__ expands to a literal of expected forms since C++11 (example), or assert this at run time even in ancient C++98. And then in C++14, we introduced binary integer literals and digit separators, which allows __LINE__ to expand to a literal of a formerly unexpected form.

As a result, if an implementation switch to use the new forms of integer literals for __LINE__, some valid C++11 program may become ill-formed or have behavior changed.

Should there be an Annex C entry for this, or should we restrict the forms for __LINE__?

Suggested resolution:

Activity

  1. jensmaurer commented on Dec 6, 2025

    @jensmaurer
    Member
  2. changed the title [-][cpp.predefined] Binary integer literal and digit separators for `__LINE__`[/-] [+]CWG3142 [cpp.predefined] Binary integer literal and digit separators for `__LINE__`[/+] on Dec 6, 2025
  3. frederick-vs-ja commented on Dec 8, 2025

    @frederick-vs-ja
    Author

    Perhaps SG22 and WG14 should also see this, as

    • wording for __LINE__ (not restricting form of integer literal/constant) was copied from C, and
    • digit separators and binary integer literals have been copied to C23 (via WG14 N2549 and WG14 N2626).
  4. jensmaurer commented on Dec 8, 2025

    @jensmaurer
    Member

    Feel free to send this to WG14.

  5. Halalaluyafail3 commented on Dec 17, 2025

    @Halalaluyafail3

    It's possible to static_assert that __LINE__ expands to a literal of expected forms since C++11 (example)

    There is an even easier way to assert this (for the form that all compilers use):

    #line __LINE__

    This requires a decimal integer literal, possibly with digit separators. Note that it will even interpret 010 as ten instead of eight. A footnote in the C standard even mentions this without saying anything about it being possibly invalid, so presumably it's intended to be valid.

  6. Halalaluyafail3 commented on Dec 18, 2025

    @Halalaluyafail3

    Additionally, digit separators being present would break the common use case of concatenating __LINE__ with an identifier:

    #define CAT(X,Y)CAT_(X,Y)
    #define CAT_(X,Y)X##Y
    #define FOO()int CAT(x,__LINE__)
    FOO();
    FOO();
    //each declaration gets a unique name from __LINE__
    //but something like x1'2 isn't a valid identifier

    See also C issue 1016 which discusses this.

  7. frederick-vs-ja commented on Dec 18, 2025

    @frederick-vs-ja
    Author

    See also C issue 1016 which discusses this.

    Yeah. I found this several days ago and attempted to mail WG14 reflector to expand the discussion for this issue.

  8. frederick-vs-ja commented on Mar 4, 2026

    @frederick-vs-ja
    Author

    C issue 1016 was recently resolved but the resolution didn't touch binary integer literals.

  9. Halalaluyafail3 commented on Mar 10, 2026

    @Halalaluyafail3

    C issue 1016 was recently resolved but the resolution didn't touch binary integer literals.

    I have created Issue 1029 which should resolve the other issues.

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions