News for hackers. Stuff that matters.
Re:Best aspects of C by Cloudef on Tuesday November 17, 2020 @10:50AM (#25125124)
Locale handling and most of the str* function in libc indeed are quite bad. The only sane function for "C strings" is snprintf.
Re:Best aspects of C by kazinator on Tuesday November 17, 2020 @11:44AM (#25125859)
Ones like strspn, strcspn, strpbrk, strchr are also sane.
Re:Best aspects of C by asveikau on Tuesday November 17, 2020 @12:09PM (#25126238)
Except when you consider what a char is. Those don't handle multi-byte sequences.
Re:Best aspects of C by kazinator on Tuesday November 17, 2020 @12:53PM (#25126971)
Yes they do. What they don't do is search for multi-byte characters. You would not use them for that; you use them to look for ASCII delimiters. You can tokenize a UTF-8 string on ASCII delimiters using functions that are oblivious to UTF-8, and this is in fact a preferred technique in many programs.
Re:Best aspects of C by asveikau on Tuesday November 17, 2020 @01:25PM (#25127509)
I think I was going for more like: strpbrk and friends can't use a multi-byte sequence as a delimiter. And if a delimiter appears as part of a multi byte sequence, you may see strange results.

In a localized world searching for delimiters also starts to make less sense. Eg. I have been told it doesn't make sense to break on whitespace for Chinese text.

To be clear, I am not saying these functions are bad or evil or to blame for their limitations (a bunch of the problem space wasn't invented yet when they were introduced), just noting they have limits. A bunch of more recent languages and libraries have the same or similar issues, too.

Re:Best aspects of C by kazinator on Tuesday November 17, 2020 @08:58PM (#25132316)
strstr can find a multi-byte character in a multi-byte sequence. There is no ISO C function to find the first occurrence of any one of a bag of multi-byte characters, though it's not difficult to write one.

> I have been told it doesn't make sense to break on whitespace for Chinese text.

It could make sense to break on whitespace in some programming language or data format that allows Chinese (and other) identifiers.

A command interpreter that allows Chinese arguments (such as file names) wants to break on spaces, as usual.

> if a delimiter appears as part of a multi byte sequence, you may see strange results.

UTF-8 was designed by a dyed-in-the-wool C-and-Unix engineer, who ensured that such a thing can't happen. No character in the 0x00-0x7F range can occur in a multi-byte character.

The byte which starts a UTF-8 character cannot occur anywhere other than at the start, which is why we can use strstr to look for it.

Re:Best aspects of C by jesuscyborg on Tuesday November 17, 2020 @02:52PM (#25128767)
Use wcspbrk.

UTF-8 continuation characters are limited to the range \200 through \300 so there's basically zero chance that if you choose something like comma as your delimiter that it's going to tokenize the middle of a multibyte sequence.

Also take into consideration that, under the hood, functions like strpbrk() are typically accelerated by CPU instructions such as PCMPISTRI which doesn't support UTF-8 natively but it does support UCS-2.

Re:Best aspects of C by loeg on Tuesday November 17, 2020 @03:20PM (#25129224)
> so there's basically zero chance that if you choose something like comma as your delimiter that it's going to tokenize the middle of a multibyte sequence.

Not just "basically;" there is no possible collision between ASCII characters and any valid multibyte encoding. This can be seen somewhat visually in this table[1] and is an intentional aspect of the UTF-8 design.

[1]: https://en.wikipedia.org/wiki/UTF-8#Encoding

Re:Best aspects of C by asveikau on Tuesday November 17, 2020 @04:09PM (#25129879)
How about with joiners and combining characters? Eg. If you encode é as U+0065, U+0301 (\x65\xcc\x81), then search for 'e' and act on the result somehow, you fail to consider the whole glyph.
Re:Best aspects of C by loeg on Tuesday November 17, 2020 @04:43PM (#25130308)
Sure. You're talking about glyphs that are composed of multiple unicode codepoints; my earlier comment is true of single codepoints only. The comment I was responding to is also talking only about single codepoints (wcspbrk cannot represent delimiters longer than a single codepoint).

On joiners / combining characters: I'd encourage using composed normalization (NFC) rather than decomposed normalization (NFD).

Just curiosity: are there any glyphs that lack a single codepoint representation, where one of the joined codepoints is an ASCII character? (That only helps after normalization, of course.)

Re:Best aspects of C by jesuscyborg on Tuesday November 17, 2020 @05:15PM (#25130651)
Yes. ASCII uses \b as the combining character mark which is a convention that's always been widely supported by typesetting programs such as less and nroff. For example, A\b_ is A̲, and you can do the same thing with apostrophe and tilde for accent marks. There's also UNICODE emojis where two codepoints in sequence get joined together as a single glyph. Never underestimate the creative ways text can be used, or that standards just codify a long history of practices.
Re:Best aspects of C by loeg on Tuesday November 17, 2020 @07:37PM (#25131772)
Er, I was asking about unicode joining, not this roff \b thing. Sorry for the confusion. I'm aware that multiple-codepoint unicode glyphs exist; I'm asking if any of those involve a codepoint in the ASCII (1-127) range which cannot be normalized to a single codepoint (e.g., e + ' normalizes to a single codepoint é).
Re:Best aspects of C by jesuscyborg on Tuesday November 17, 2020 @08:08PM (#25132015)
Of course. Take for example mͫ (m+m) there's no way to represent that as a single codepoint. Combining marks can also be overlaid multiple times, e.g. m͚ͫ (m+m+∞) so the number of glyphs you can create is limitless. There's only a tiny number of the combinations that are possible which have a tinier normalized form. The new UNICODE combining marks work by almost exactly the same principles as the \b ASCII combining mark. That's why I mentioned it earlier.
Re:Best aspects of C by loeg on Tuesday November 17, 2020 @08:43PM (#25132227)
Thanks!
Re:Best aspects of C by kazinator on Tuesday November 17, 2020 @09:04PM (#25132345)
In what data format or programming language is 'e' a delimiter? One situation is floating-point constants, where 'e' is a delimiter indicating the exponent. However, if an é occurs in the middle of such a constant, whether as a single code point or a combined character, that is an error. The 'e' must be followed by an optional sign and one or more decimal digits.

The ISO C library string handling stuff is for systems programming, not for scanners and parsers for natural written language.

Re:Best aspects of C by Cloudef on Tuesday November 17, 2020 @11:57AM (#25126057)
True. With the snprintf comment I was mostly pointing out str* functions that are designed to either modify or concatenate strings.
Re:Best aspects of C by ringshall on Tuesday November 17, 2020 @08:35PM (#25132177)
It's been a long time since I've used C, but I recall strncpy being safe. I assume from context that I'm wrong, though.
Re:Best aspects of C by WalterBright on Tuesday November 17, 2020 @10:47PM (#25132981)
Every time I review code and see strncpy, I look closer because it's always used incorrectly. It's always about the terminating 0. Is the 0 there or not? Is the 0 part of n or not? Does the destination have to be n+1 in size for the 0?

I quit using it myself because I could never remember just what the exact protocol was for 0.

Re:Best aspects of C by Gibbon1 on Wednesday November 18, 2020 @03:37AM (#25134434)
Yeah used naively strncpy leaves you an unterminated string. Also like all of them it's up to the caller to predetermine if they will fail if called. So instead of having the checks in one place inside the string function. You have them scattered all over the code if at all.
Re:Best aspects of C by WalterBright on Wednesday November 18, 2020 @07:09AM (#25135886)
The irony of strncpy is it's supposed to eliminate memory corruption errors, but instead is a prolific source of them.
Re:Best aspects of C by Gibbon1 on Wednesday November 18, 2020 @11:52PM (#25146354)
I think I read somewhere the provenience of strncpy was to copy strings into a fixed length field which is why it has the deranged behavior of not terminating the string. Think file systems where the max file name is 8 characters. Or compilers that truncated variable names at 31.
Re:Best aspects of C by johntb86 on Tuesday November 17, 2020 @10:48PM (#25132986)
Strncpy doesn't add a \0 if it truncates the string, so the user has to remember to do that.
Re:Best aspects of C by Cloudef on Tuesday November 17, 2020 @11:37PM (#25133266)
strncpy is one of the trap functions. It's better avoided. Write your own or use snprintf.