Skip to content

Generalize const_cast(), and use it more.#1374

Open
alejandro-colomar wants to merge 3 commits intoshadow-maint:masterfrom
alejandro-colomar:const_cast
Open

Generalize const_cast(), and use it more.#1374
alejandro-colomar wants to merge 3 commits intoshadow-maint:masterfrom
alejandro-colomar:const_cast

Conversation

@alejandro-colomar
Copy link
Collaborator

@alejandro-colomar alejandro-colomar commented Oct 18, 2025


Revisions:

v1b
  • Rebase
$ git rd 
1:  ce42f9144 = 1:  2c3f13ec1 lib/cast.h: const_cast(): Pass through other types
2:  76d74d912 = 2:  fea4e1cea lib/atoi/a2i.h: Use const_cast() instead of a raw cast
3:  64085c62c = 3:  e92c7e61f lib/string/: Use QChar_of() to simplify some macros
v1c
  • Rebase
$ git rd 
1:  2c3f13ec1 = 1:  f03098a32 lib/cast.h: const_cast(): Pass through other types
2:  fea4e1cea = 2:  74b8aa829 lib/atoi/a2i.h: Use const_cast() instead of a raw cast
3:  e92c7e61f = 3:  226fc059e lib/string/: Use QChar_of() to simplify some macros
v1d
  • Rebase
$ git rd 
1:  f03098a32 = 1:  36b190225 lib/cast.h: const_cast(): Pass through other types
2:  74b8aa829 ! 2:  92d03967c lib/atoi/a2i.h: Use const_cast() instead of a raw cast
    @@ lib/atoi/a2i.h
                unsigned long long: strtou_noneg                      \
     -  )(s, (char **) endp_, base, min_, max_, &status);             \
     +  )(s, const_cast(char **, endp_), base, min_, max_, &status);  \
    -                                                                       \
    +                                                                 \
        if (status != 0)                                              \
                errno = status;                                       \
3:  226fc059e ! 3:  b55a55aeb lib/string/: Use QChar_of() to simplify some macros
    @@ lib/string/strcmp/strcaseprefix.h
      #define strcaseprefix(s, prefix)                                      \
     -({                                                                    \
     -  const char  *p_;                                              \
    --                                                                      \
    +-                                                                \
     -  p_ = strcaseprefix_(s, prefix);                               \
    --                                                                      \
    +-                                                                \
     -  _Generic(s,                                                   \
     -          const char *:                     p_,                 \
     -          const void *:                     p_,                 \
    @@ lib/string/strcmp/strprefix.h
      #define strprefix(s, prefix)                                          \
     -({                                                                    \
     -  const char  *p_;                                              \
    --                                                                      \
    +-                                                                \
     -  p_ = strprefix_(s, prefix);                                   \
    --                                                                      \
    +-                                                                \
     -  _Generic(s,                                                   \
     -          const char *:                     p_,                 \
     -          const void *:                     p_,                 \
v1e
  • Rebase
$ git rd 
1:  36b190225452 = 1:  dbedfb1d387a lib/cast.h: const_cast(): Pass through other types
2:  92d03967cf26 = 2:  ec48e1275c11 lib/atoi/a2i.h: Use const_cast() instead of a raw cast
3:  b55a55aebc5d = 3:  95240c20c060 lib/string/: Use QChar_of() to simplify some macros
v1f
  • Rebase
$ git rd 
1:  dbedfb1d = 1:  c2bb0e09 lib/cast.h: const_cast(): Pass through other types
2:  ec48e127 = 2:  e4cdcf42 lib/atoi/a2i.h: Use const_cast() instead of a raw cast
3:  95240c20 = 3:  4f994530 lib/string/: Use QChar_of() to simplify some macros
v1g
  • Rebase
$ git rd 
1:  c2bb0e09 = 1:  087bcb12 lib/cast.h: const_cast(): Pass through other types
2:  e4cdcf42 = 2:  555dbd8f lib/atoi/a2i.h: Use const_cast() instead of a raw cast
3:  4f994530 = 3:  e37687a5 lib/string/: Use QChar_of() to simplify some macros

@alejandro-colomar alejandro-colomar force-pushed the const_cast branch 2 times, most recently from a6f929b to 73cf573 Compare October 19, 2025 08:24
@alejandro-colomar alejandro-colomar force-pushed the const_cast branch 3 times, most recently from b8464aa to aa569b9 Compare November 1, 2025 19:56
@alejandro-colomar alejandro-colomar force-pushed the const_cast branch 6 times, most recently from 7ab1ed9 to c3b4fd7 Compare November 10, 2025 12:14
@alejandro-colomar alejandro-colomar force-pushed the const_cast branch 3 times, most recently from d0ca9b9 to a9f17dd Compare November 19, 2025 21:37
@alejandro-colomar alejandro-colomar marked this pull request as ready for review November 28, 2025 12:30
@alejandro-colomar alejandro-colomar force-pushed the const_cast branch 2 times, most recently from e92c7e6 to 226fc05 Compare December 7, 2025 14:07
@alejandro-colomar alejandro-colomar self-assigned this Dec 11, 2025
@alejandro-colomar
Copy link
Collaborator Author

Cc: @kees

@alejandro-colomar alejandro-colomar force-pushed the const_cast branch 2 times, most recently from 95240c2 to 4f99453 Compare February 26, 2026 16:46


#define const_cast(T, p) _Generic(p, const T: (T) (p))
#define const_cast(T, p) _Generic(p, const T: (T) (p), default: (p))
Copy link

Choose a reason for hiding this comment

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

A down-side of this change is that if T is ever already const-qualified, this code will fail to build (on at least Clang), as const const ... is not a valid type qualifier. The original _Generic() macros handled this by matching const with a pass-thru, and only adding const when it was missing.

Copy link
Collaborator Author

@alejandro-colomar alejandro-colomar Feb 26, 2026

Choose a reason for hiding this comment

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

@kees

$ git log --pretty=reference lib/cast.h
eb71706b (*/: Fix including <config.h> as system header, 2025-07-15)
69f74dbf (lib/cast.h: const_cast(): Reimplement with _Generic(3), 2024-05-15)
e9fc8fc7 (lib/cast.h: const_cast(): Add macro for dropping 'const', 2024-01-07)

By "the original _Generic() macros" you mean this, right?

$ git show 69f74dbf:lib/cast.h | grepc -h const_cast
#define const_cast(T, p)  _Generic(p, const T:  (T) (p))

69f74db (2024-06-04; "lib/cast.h: const_cast(): Reimplement with _Generic(3)")

I think that would also fail for const char *, as it would expand const T as const const char *, right?

It won't hurt; if the type is convertible, it will be accepted; and if
it's not convertible, the compiler will reject it at call site.
This 'default' branch allows converting a QChar** into a char**.

Signed-off-by: Alejandro Colomar <alx@kernel.org>
This allows grepping for casts more easily.
It also reduces the damage of a bogus cast.

Signed-off-by: Alejandro Colomar <alx@kernel.org>
Signed-off-by: Alejandro Colomar <alx@kernel.org>
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.

2 participants