Earlier quoted context omitted.
There is indeed just convention. The language defines string constants similar to what you say[1] (an array of characters, terminated by a null character), but in the language itself there's no way to declare that a function takes a string rather than a pointer to a character. Alternatively if you work with a fixed-sized character array, there's nothing separating it from "just" an array of characters that are not nu…
That means that the strings aren't properly reflected in the type system. But the existence of string literals with a very definite in-memory layout means that it's not just a convention even so.
C Strings and my slow descent to madness
121–130 of 329 posts
Re: C Strings and my slow descent to madness
#122It's unfortunate the author put the arrays-are-pointers thing so early in the doc, as that's a very beginner-to-C mixup and really nothing at all to do with strings. Otherwise, yep. It's pretty bad. C is a great language, but its string handling is definitely garbage. You get used to it pretty quick, and it's not hard to write a handful of sane wrappers or a simple string library for your own use, but the standard li…
This is almost a cliche among many C language lawyers and/or Stack Overflow answer-rich people and I know you mean well, but: arrays are not pointers. In some contexts, the name of an array decays to a pointer to its first element. That is a better way of putting it, and it's a (much) weaker statement. Edit: if they were the same, this code: int foo[] = {1, 2, 3}; int *bar = foo; printf("%zu and %zu\n", sizeof foo, s…
int a[] = {1, 2, 3}
int (*p1)[3] = &a; // ok
int (*p2)[3] = &a[0]; // not ok
int *p3 = &a; // not ok
(It should be noted that these will compile with warnings in C due to implicit conversions via void*, but you're still risking UB if you actually use the resulting value. They are all errors in C++ because it doesn't have implicit conversion from void*.)Re: C Strings and my slow descent to madness
#123> Our last function is strcmp. It looks at two strings and determines whether they are equal to each other or not. If they are it returns 0. If they aren’t it returns 1. No it doesn’t. RETURN VALUES The strcmp() and strncmp() functions return an integer greater than, equal to, or less than 0, according as the string s1 is greater than, equal to, or less than the string s2. The comparison is done using unsigned charac…
I don't have MacOs to prove it but I believe `strcmp` on MacOs returns either 0, 1 or -1
Re: C Strings and my slow descent to madness
#124Earlier quoted context omitted.
That means that the strings aren't properly reflected in the type system. But the existence of string literals with a very definite in-memory layout means that it's not just a convention even so.
But you can't use those string literals in any way without relying on convention.
char s[3] = "foo"; // not null-terminated!Re: C Strings and my slow descent to madness
#125If you are using C and do some non-trivial work with strings you should either use a good library to handle strings or build your own. It is not that difficult in practice. The old C std lib is, in my opinion, outdated, obsolete and a very bad fit for complex string handling, especially on the memory management side. In my own framework, the string management module is using a dedicated memory allocator and a "high l…
> the C std lib is the weakest part of the C language and it should only be used as a fallback. I've been musing for a while now: what would it look like if we were to discard the C library and design a new one, leaving the language itself intact?
Re: C Strings and my slow descent to madness
#126The 'n' in strncpy is mainly there to help you avoid overrunning the destination, it does not guarantee whatever makes in there is null-terminated.
This is why you should always explicitly set the last byte to zero after using strncpy (and never ever use strcpy).
char dest[16];
strncpy(dest, src, 15);
dest[15]=0;Re: C Strings and my slow descent to madness
#127If you are using C and do some non-trivial work with strings you should either use a good library to handle strings or build your own. It is not that difficult in practice. The old C std lib is, in my opinion, outdated, obsolete and a very bad fit for complex string handling, especially on the memory management side. In my own framework, the string management module is using a dedicated memory allocator and a "high l…
> the C std lib is the weakest part of the C language and it should only be used as a fallback. I've been musing for a while now: what would it look like if we were to discard the C library and design a new one, leaving the language itself intact?
my_function(my_var, 3.6, "bzarflo", my_other_var, false);
The string handling functions are part of the story, but the null-terminated char * is produced when the compiler reaches a string literal, and writing code without being allowed to just use string literals when it's convenient tends to feel like coding with oven mitts on.Re: C Strings and my slow descent to madness
#128Earlier quoted context omitted.
> the C std lib is the weakest part of the C language and it should only be used as a fallback. I've been musing for a while now: what would it look like if we were to discard the C library and design a new one, leaving the language itself intact?
Glib answer (but also relevant because mentioned in the article, too): it would look a lot like how a lot of people write C++.
A Freudian slip, methinks.
Re: C Strings and my slow descent to madness
#129Re: C Strings and my slow descent to madness
#130Earlier quoted context omitted.
The thing that annoys me the most about strlcpy is that it is supposed to be safer, but what happens in the case where the source string is not properly NULL terminated? You might think that it will stop at the character limit you specified, but that's not what it does. It just blows on past the end of the buffer looking for a \0 until it either finds one or causes a segmentation violation. IMHO I would like it much…
Linux's strscpy addresses these issues.