strlcpy returns offset of dst + len of src which requires strlen(src) which isn't optional and sort of sucks imo.
Something very similar but that doesn't do strlen(src) such as https://godbolt.org/g/Etpuhz would be better.
Well one could argue that in C a string is not a string unless it's NUL terminated...
It's a choice they made to make it easy to detect truncation. If you don't care about the return value of strlcpy you can modify it to skip that part (which IMO will make it worse) but get rid of traversing src until \0 is found.
If you know you're working with non-terminated "strings" then just use memcpy instead.
If you're using proper functions you shouldn't end up with a non NUL-terminated string in the first place, although there are shortcomings in the commonly used libraries here unfortunately yes. It's hard to create a function that solves all problems.
(Side note: IMO The return value of latest OpenBSD version of strlcat (cat not cpy) is a bit weird when size is smaller than strlen(dst))
My issue isn't that src is or isn't NUL terminated (strings in c absolutely must be NUL terminated) its that strlcpy requires a call to strlen (probably inlineable with lto) which is going to be a lot slower than not. Also there is a bug in my 'strmcpy' in the last for loop it should be n && *s
I've gone through a lot of exercises[0][1] from this site especially on how to implement a linked list in C. The time spent from the tutorial was absolutely worth while. I feel happy and satisfied with my self after solving one problem at a time.
For those who already know the syntax of C but wanted to learn more, the links I mentioned is a good exercise and opens up a lot of possibilities on what you can implement. You'll soon be able to realize the importance of linked list and why you'll want to use a linked list instead of just plain arrays.
I tried to appreciate your response, but I cannot fairly judge the code. For example, those could be performance uncritical parts of code or remnants of 20 year old code where the cache was less effective than now. Are 2000 search results a lot in a source of this size?
Cache, as opposed to 20+ years ago, or whenever the pattern was developed, is indeed a thing that everyone is using just now.
Storing strings as a linked list of characters in Haskell was a design mistakes imho, which lead to the proliferation of various efficient string types implemented in libraries.
Some operations are faster on linked list than on vectors (insert on beginning, or on specified iterator position, delete iterator position). They also use less memory in some use cases. I was once optimizing transactional tree structure which internally used std::vector in each node. In most real use cases there was just one item in each vector, but vector preallocated 16 items. So changing to linked list lowered memory consumption significantly without measurable performance impact. The same applied for hash table vs. RB tree. All basic data structures can be useful, you just have to choose proper one.
IMHO, linked lists can be useful in conjunction with other data structures without hurting performance too much. An open hash table with a linked list in each bucket need only involve pointer chasing in case of collisions, which can be made arbitrarily rare by making the number of buckets large enough. In this way, there's a graceful performance degradation under unexpectedly heavy loads rather than hard limitations. I would be interested to read well informed contrasting opinions.
How on earth can you make such a statement about a fundamental data structure? Please, take CS101 before you you start throwing these kind of assertions around.
My favourite language is Lisp, in which I use "linked" lists all the time, but I never use them in C. Use of lists without a garbage collector and either dynamic typing (as in Lisp) or strong static typing (as in Haskell) is a pain, and C has none of these built in. This means that, in C, you need to allocate memory every time you add something to your list, and hold the pointer to it in order to free it later. You also need to keep track of which types are stored, and where.
If your problem requires a lot of list processing, use a language more suitable for it. Otherwise, use extensible arrays, which are easy to implement in C.
conceit also pointed out that lists also increase the likelihood of cache misses, which slows down the program a little bit. Many C programmers care about that. I don't share their priorities - it is important to me, but less so than correctness, ease of programming (allowing more time for exploration and finding a more efficient algorithm), and response times.
Just allocate all the list items from a big pool of memory that you own. When you're done, throw the whole lot away in one go. Languages like C++ tend to encourage micromanagement of data but it's not the only way to do things.
I too pronounce it that way, since I learned C from books and just read it as it was printed.
I later noticed some people do pronounce it "car" which just seems odd. Why change it, if it doesn't save a syllable? It's not a truncation of how "character" is said either, because that's a different vowel sound.
Saying 'car' causes problems when learning C++, because all OOP examples on composition start "Car has-an Engine".
I remember reading the "care as in character" thing years ago and just boggling at it -- who on earth makes character start with care? (As a British person, I think the first syllable of character rhymes with cat. There isn't a word that sounds like that but ending in r.) So rather than settle the question for me, it just dug the hole deeper.
Listening to Kernighan, I can just about hear what that remark meant.
Bollocks, pronounced char as in "char". I did not know this was even in dispute. Not that i care how anyone else pronounces it, i just thought it was blindingly obvious since we already have an English word spelled exactly the same as what we use in code to declare the thing.
Well yes, but saying pronounced char as in char doesn't really get the pronunciation across unambiguously, especially when half the world seems to pronounce it something else and Irishmen have their own spin ;)
I've always pronounced it as 'care', not because of how the identifier is spelled but because it's the first syllable of the word 'character'.
I don't think there's a consensus between car/char/care, though, even among C's creators. But if there was, I would vote for 'care'.
I always thought SQL was another weird one. When discussing the language itself, you can say 'sequel' or 'ess queue ell' interchangeably, but when referring to a database that has "SQL" in its name, there is a DB-specific one true pronunciation:
* SQL Server: 'sequel server'
* PostgreSQL: 'post gress queue ell'
* SQLite: 'sequel light'
* MySQL: 'my ess queue ell'
There's no complete consensus on any of those- just a preponderance of one, or an officially endorsed pronunciation in a FAQ someplace.
I've also heard 'my squeal' for MySQL, breaking out of the 'sequel'/'ess queue ell' duopoly altogether.
> because it's the first syllable of the word 'character'.
Except the first syllable of 'character' is neither 'car' nor 'care', unless you have a really weird accent or are intentionally making fun of the English upper class.
PS: I always liked "squirrel" for SQL but sadly that one never got much traction.
'Care' rhymes with 'bear', 'share', 'fair'; 'car' rhymes with 'bar', 'far', 'mar'. 'Character', to me, is pronounced 'car-ack-ter' with the emphasis on the first syllable. It doesn't sound anything like 'care'.
Conversations like this are hard because accent doesn't transmit through text. I'm Irish.
Ohhhh, that's where the discrepancy is coming from. I didn't know it was pronounced 'car-ack-ter' with an Irish accent. I was thinking in terms of an American accent which is where the confusion came from.
The "listen" button here pronounces the words with an American accent:
Oops, I was afraid of that. I was hoping the .com domain would have an influence on which voices were picked. I can hear the difference by going to https://translate.google.co.uk/ though
What's going here is that most Americans have what's known as the marry-merry-Mary merger[1]. Virtually all English speakers outside of North America, as well as some Americans, mostly on the East Coast, pronounce the vowels in these three words differently -- marry is pronounced /mæri/ (/æ/ is the vowel in "cat"), merry is /mɛri/ (/ɛ/ is the vowel in "pet"), and Mary is /meri/ (/e/ is the vowel in "bait"). In those dialects, any vowel can proceed an /r/ that's intervocalic (i.e., both preceded and followed by another vowel), so /r/ acts like any other consonant in that sense.
However, in most American dialects, marry-merry-Mary are all merged and pronounced identically (IPA: /mɛɹi/, though the exact vowel isn't important here, and all three vowels generally sound the same to merged speakers). Furthermore, the first syllable of all these words is usually pronounced the same as the vowel in mare (/mɛɹ/).
So let's put this together. The word "care" is pronounced /kɛr/ in both merged and unmerged dialects (or /kɛː/ if you don't pronounce the /r/ there). In unmerged dialects, the word "character" is pronounced /kærəktər/, so it doesn't make sense that you'd truncate it to /kær/, because /ær/ (or /æː/) at the end of a syllable doesn't occur in any English dialect[2]. In merged dialects, however, "character" is pronounced /kɛrəktər/, so it makes sense to truncate it to /kɛr/, which is a homophone of "care".
Your post looks interesting and might well be 100% correct but I don't know - nor do I know anyone who knows - what the various little pronunciation guides or whatever they're called mean. It's why people tend to say "car as in carpet".
No, "car as in character" is still. Car as in carpet, char as in chart - simple and doesn't require a course in IPA, which may I remind you precisely nobody understands.
I don't know what happened to my post but i meant "car as in character is stupid/ambiguous". But it's perfectly possible to understand "car as in carpet" and it's generally possible to find a similar pronunciation of a sound.
"Plenty of people" is misleading. Plenty as in thousands, millions of people worldwide, possibly, not not plenty as a percentage of the english people world. I'd be surprised if more than 5% of english speakers look at an IPA description of a sound and do anything other than go "what the fuck does that mean?".
I want to love ddd, really I do, conceptually it is awesome and beautiful. In practice it is (IME) buggy (almost) to the point of uselessness. It's been a couple of years since I last used it, but it was last updated around 2009 :-(
ddd isn't my day-to-day debugger but I sometimes break it out when I need to visualize a data structure or keep track of multiple values when doing some more difficult debugging tasks.
Oh for sure, I've used it a fair bit, it can be an absolute lifesaver for RE work or building simple VMs, for instance where you need to grok a structure in its fullness.
I'm in the same boat. I've tried it out a few times and it's always a crashy mess. I want to like it, but the project seems to have been abandoned in a barely usable state.
This is an enjoyable comment section (rare to say). The arguments about the pronunciation of the char keyword is all part of being C programmers. This is great. :-)
The "C Programming Cleverness and Ego Issues" is a good bit of advice:
> Build programs that do something cool rather than
programs which flex the language's syntax. Syntax -- who cares?
Otherwise, I'd never heard of/seen the `#pragma once` preprocessor directive. (Not that I do that much C programming!) How common is it to use this over include guards?
They might have used MSVC for their exercises on this course. They're not using some C99 features such as stdint.h, which were not available in MSVC when this article was written.
It depends. Clang, GCC and the Intel C++ compiler all support #pragma once perfectly. Personally, I prefer it, as it is only one line rather than three and I don’t have to think of a unique name for the header guard. Supposedly it breaks if you play weird tricks with the filesystem (s.t. the compiler thinks two identical files are actually different), but I have never encountered such breakage.
93 comments
[ 2.7 ms ] story [ 158 ms ] threadBut as of 2003, support for C99 wasn't very widespread, so omitting <stdint.h> was understandable.
I'd love to see an updated version.
It's a choice they made to make it easy to detect truncation. If you don't care about the return value of strlcpy you can modify it to skip that part (which IMO will make it worse) but get rid of traversing src until \0 is found.
If you know you're working with non-terminated "strings" then just use memcpy instead.
If you're using proper functions you shouldn't end up with a non NUL-terminated string in the first place, although there are shortcomings in the commonly used libraries here unfortunately yes. It's hard to create a function that solves all problems.
(Side note: IMO The return value of latest OpenBSD version of strlcat (cat not cpy) is a bit weird when size is smaller than strlen(dst))
For those who already know the syntax of C but wanted to learn more, the links I mentioned is a good exercise and opens up a lot of possibilities on what you can implement. You'll soon be able to realize the importance of linked list and why you'll want to use a linked list instead of just plain arrays.
[0] - http://cslibrary.stanford.edu/103/LinkedListBasics.pdf
[1] - http://cslibrary.stanford.edu/105/LinkedListProblems.pdf
https://github.com/torvalds/linux/search?utf8=%E2%9C%93&q=IN...
That's unbearable. They should just redo this in JavaScript. That's what everyone uses nowadays. Or so they say on here, if I understand correctly.
Cache, as opposed to 20+ years ago, or whenever the pattern was developed, is indeed a thing that everyone is using just now.
The best data structure or algorithm to use is usually problem-dependent.
> ... why you'll want to use a linked list instead of just plain arrays
If your problem requires a lot of list processing, use a language more suitable for it. Otherwise, use extensible arrays, which are easy to implement in C.
conceit also pointed out that lists also increase the likelihood of cache misses, which slows down the program a little bit. Many C programmers care about that. I don't share their priorities - it is important to me, but less so than correctness, ease of programming (allowing more time for exploration and finding a more efficient algorithm), and response times.
Just allocate all the list items from a big pool of memory that you own. When you're done, throw the whole lot away in one go. Languages like C++ tend to encourage micromanagement of data but it's not the only way to do things.
Pronounced 'car'? Bollocks. Pronounced char as in charred.
It's /kɛər/, as you can see here: https://en.wikipedia.org/wiki/Help:IPA_for_English
And, for the record, I have the Mary-marry-merry merger: https://en.wikipedia.org/wiki/English-language_vowel_changes...
It's as noob as when someone pronounces nginx [njinkx] instead of [engin-x], or linux as [li-nux] instead of [lin-ux].
C Infrequently Asked Questions #19.26, https://www.seebs.net/faqs/c-iaq.html
I later noticed some people do pronounce it "car" which just seems odd. Why change it, if it doesn't save a syllable? It's not a truncation of how "character" is said either, because that's a different vowel sound.
Saying 'car' causes problems when learning C++, because all OOP examples on composition start "Car has-an Engine".
https://www.youtube.com/watch?v=de2Hsvxaf8M&t=2m35s
I remember reading the "care as in character" thing years ago and just boggling at it -- who on earth makes character start with care? (As a British person, I think the first syllable of character rhymes with cat. There isn't a word that sounds like that but ending in r.) So rather than settle the question for me, it just dug the hole deeper.
Listening to Kernighan, I can just about hear what that remark meant.
(I say char myself, like the fish)
I've always pronounced "char" as "car". Dunno why, I learned C from a book, so no one got to tell me I was wrong.
Not that I say it that way, I've always heard and said var-char
char grinned;
[0] https://m.youtube.com/watch?v=eELH0ivexKA
I don't think there's a consensus between car/char/care, though, even among C's creators. But if there was, I would vote for 'care'.
I always thought SQL was another weird one. When discussing the language itself, you can say 'sequel' or 'ess queue ell' interchangeably, but when referring to a database that has "SQL" in its name, there is a DB-specific one true pronunciation:
* SQL Server: 'sequel server'
* PostgreSQL: 'post gress queue ell'
* SQLite: 'sequel light'
* MySQL: 'my ess queue ell'
There's no complete consensus on any of those- just a preponderance of one, or an officially endorsed pronunciation in a FAQ someplace.
I've also heard 'my squeal' for MySQL, breaking out of the 'sequel'/'ess queue ell' duopoly altogether.
Except the first syllable of 'character' is neither 'car' nor 'care', unless you have a really weird accent or are intentionally making fun of the English upper class.
PS: I always liked "squirrel" for SQL but sadly that one never got much traction.
Conversations like this are hard because accent doesn't transmit through text. I'm Irish.
The "listen" button here pronounces the words with an American accent:
https://translate.google.com/#en/ja/character%0Acare
I think that feature must be localised -- here it gives me a (female) voice with an English accent, and the two words sound quite different.
It does if you use IPA.
The only way I could pronounce it 'care' is if I were from the southern hemisphere.
However, in most American dialects, marry-merry-Mary are all merged and pronounced identically (IPA: /mɛɹi/, though the exact vowel isn't important here, and all three vowels generally sound the same to merged speakers). Furthermore, the first syllable of all these words is usually pronounced the same as the vowel in mare (/mɛɹ/).
So let's put this together. The word "care" is pronounced /kɛr/ in both merged and unmerged dialects (or /kɛː/ if you don't pronounce the /r/ there). In unmerged dialects, the word "character" is pronounced /kærəktər/, so it doesn't make sense that you'd truncate it to /kær/, because /ær/ (or /æː/) at the end of a syllable doesn't occur in any English dialect[2]. In merged dialects, however, "character" is pronounced /kɛrəktər/, so it makes sense to truncate it to /kɛr/, which is a homophone of "care".
[1]: https://en.wikipedia.org/wiki/English-language_vowel_changes...
[2]: Except Irish English, see https://news.ycombinator.com/item?id=11673067.
[3]: I speak a merged dialect, and pronounce "char" as /kɛr/ when I'm reading C code.
https://en.m.wikipedia.org/wiki/International_Phonetic_Alpha...
This "'foo' as in 'bar'" stuff is worse than useless most of the time, as you've just been shown.
Plenty of people understand IPA.
> No, "car as in character" is still.
It's still completely incomprehensible unless you know which vowel sound is meant, which is the whole point of this sub-thread.
"Plenty of people" is misleading. Plenty as in thousands, millions of people worldwide, possibly, not not plenty as a percentage of the english people world. I'd be surprised if more than 5% of english speakers look at an IPA description of a sound and do anything other than go "what the fuck does that mean?".
> char: /keir/, /char/, /kar/, n.
Here's a proper reference on C99 and C11:
http://en.cppreference.com/w/c
And see also reallocarray.
It's far from perfect but still a useful tool.
> Build programs that do something cool rather than programs which flex the language's syntax. Syntax -- who cares?
Otherwise, I'd never heard of/seen the `#pragma once` preprocessor directive. (Not that I do that much C programming!) How common is it to use this over include guards?
Not very. It works in Microsoft's C compiler but can't be relied on elsewhere.
[1] http://www.literateprogramming.com/ctraps.pdf