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.
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.
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.
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.
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.
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.
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.
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 :-(
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.
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.
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. :-)
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
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?
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.
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.
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.
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?".
'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
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 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".
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