cppreference показывает эти прототипы для strchr():
char *strchr( const char *str, int ch ); (1)
/*QChar*/ *strchr( /*QChar*/ *str, int ch ); (2) (since C23)
и предлагает такое объяснение второй версии:
Типовая функция, эквивалентная (1). Пусть T — неквалифицированный символьный тип объекта.
- Если
strимеет типconst T*, тип возвращаемого значения —const char*.- В противном случае, если
strимеет типT*, тип возвращаемого значения —char*.- В противном случае поведение не определено.
Что это QChar*? Это новый тип?
Если да, то поддерживают ли его уже GCC и/или Clang? Могу ли я использовать его в своем собственном коде приложения?
См. open-std.org/jtc1/sc22/wg14/www/docs/n3020.pdf
По сути, позволяет прозрачно использовать strchr() и некоторые другие функции с константными или неконстантными указателями на символы и получать обратно тот же тип.
Здесь я написал небольшой обзор изменений C23, которые, скорее всего, повлияют на среднего программиста: Что такое C23 и почему меня это должно волновать?





В течение многих лет strchr() (и некоторые другие функции) принимали аргумент указателя на константный символ (на строку, заканчивающуюся нулем) и возвращали неконстантный указатель на место где-то внутри строки (что может быть проблематичным, если кто-то затем попытается написать в это место через этот указатель, хотя он не должен быть изменяемым). Новые версии Qualified Char представляют собой универсальные функции, которые при передаче указателя const char возвращают указатель const char, а при передаче обычного указателя char возвращают то же самое.
Предложение с обоснованием и полным списком затронутых функций представляет собой PDF-файл , который можно прочитать здесь .
Я не знаю, поддерживают ли это какие-либо компиляторы/стандартные библиотеки.
Я реализовал basename() и подумал, что смогу использовать это QChar * в качестве аргумента и типа возвращаемого значения.
@Харит, это не настоящий тип (обратите внимание, как это закомментировано в документации cppreference?). Вам придется что-то сделать с _Generic(), чтобы получить эффект.
Понимаю, я был в замешательстве, действительно ли это тип, который я мог бы использовать в коде приложения или нет.
На самом деле это даже не настоящая функция, а просто макрос. При вызове она ведет себя более или менее как функция, поэтому cppreference использует для ее выражения синтаксис, подобный функции, но обратите внимание, что в ней также упоминается, что если вы не вызываете ее обычным способом, вместо этого выбирается простая старая функция.
В связанном PDF-файле есть пример реализации макросов, но он связан с темной магией, которую я не понимаю.
@harith Стандартная реализация библиотеки может выглядеть примерно так: godbolt.org/z/91Yc4rbMr. Можно использовать _Generic для квалифицированных типов указателей, а не только для простых переменных, поскольку операнд _Generic подвергается «преобразованию lvalue» (согласно C17). Говоря простым языком, он может определить разницу между const char* и char*, но не между const char и char.
@Lundin Да, это то, что я тоже ожидал увидеть, а не ужасный трюк с макросами, который я видел в предложении, которым поделился Шон. Спасибо, это полезно для меня.
Возможно, будет полезное чтение. Это был один из первых результатов поиска в Google «qchar c23».