4

cppreference shows these prototypes for strchr():

char *strchr( const char *str, int ch );     (1)    
/*QChar*/ *strchr( /*QChar*/ *str, int ch ); (2) (since C23)

and offers this explanation for the second version:

Type-generic function equivalent to (1). Let T be an unqualified character object type.

  • If str is of type const T*, the return type is const char*.
  • Otherwise, if str is of type T*, the return type is char*.
  • Otherwise, the behavior is undefined.

What is this QChar*? Is it a new type?

If so, does GCC and/or Clang support it already? Can I use it in my own application code?

4

1 Answer 1

4

For many years, strchr() (and some other functions) took a const char pointer argument (to a 0 terminated string), and returned a non-const pointer to a location somewhere inside the string (which can be problematic if someone then tries to write to that location though that pointer when it's not supposed to be mutable). The new Qualified Char versions are generic functions that, when passed a const char pointer, return a const char pointer, and when passed a regular char pointer, return the same.

The proposal with rationale and complete list of affected functions is a PDF that can be read here.

8
  • I do not know if any compilers/standard libraries support it yet
    – Shawn
    Commented May 17 at 22:28
  • I was implementing basename(), and thought I might be able to use this QChar * as the argument and return type.
    – Harith
    Commented May 17 at 22:34
  • @Harith it's not an actual type (notice how it's commented out in the cppreference documentation?). You'd have to do something with _Generic() to get the effect.
    – Shawn
    Commented May 17 at 22:37
  • 1
    In fact, it is not even an actual function, just a macro. It behaves more or less like a function when called, so cppreference uses a function-like syntax to express it, but notice that it also mentions that if you do not call it in the usual way, the plain old function is picked instead.
    – IS4
    Commented May 17 at 22:41
  • 1
    @harith The standard lib implementation might look something like this: godbolt.org/z/91Yc4rbMr. It's fine to use _Generic on qualified pointer types, not just on plain variables, since the operand of _Generic undergoes "lvalue conversion" (as per C17). In plain English, it can tell the difference between const char* and char* but not between const char and char.
    – Lundin
    Commented May 20 at 9:34

Not the answer you're looking for? Browse other questions tagged or ask your own question.