16 ms·
Do people really think C is some mysterious, inscrutable language? "To many programmers, this makes C scary and evil." Is this actually true for people? I fin
by rpearl 15y ago
Do people really think C is some mysterious, inscrutable language?
"To many programmers, this makes C scary and evil."
Is this actually true for people? I find C code generally very easy and straightforward to understand; there's not any magic behind the scenes, like there is in any language that's more "high level" than C.
- ramidarigaz 15y agoMany of the friends I made in my CS classes were terrible with pointers. I never really understood why they didn't grasp pointers, but it was a major stumbling block for them in C/C++
- alderssc 15y agoI would hazard to guess its due to two things: 1) a lack of understanding about how the machine works, and in particular the way the memory is organized; and 2) lack of explanation of why anyone would need to use pointers. Introducing pointers in the context of a linked list, or explaining call-by-reference would probably help make things more concrete.
- younata 15y agoI have friends who had to take an intro to C++ as their first (and only) programming class. I heard them talking about passing arguments to functions as "call by reference" many times, and it was obvious they had no idea what they were talking about, just regurgitating what the instructor said.
- daxelrod 15y agoFor me, the indirection of pointers was one of the fundamental CS concepts that required real effort to understand. Before that point, I had never clearly separated the concept of a variable and its value. It took a huge conceptual leap to think about a variable that didn't hold a value, but rather, the location of a value. It took some serious mental gymnastics to deal with pointers n-levels deep. Mind you, this was actually Perl references, not pointers, so I didn't even have to try to comprehend doing math on them. After a while, of course, it became second nature. My favorite aspect of CS is that every so often, I run into a wall of conceptual understanding that requires completely changing how I think in order to move forward. Have you never had moments like this, or were they just different topics?
- ramidarigaz 15y agoActually learning about the stack was one of my big 'aha!' moments. I sorta' knew it existed, but I didn't really comprehend it.
- gregjor 15y agoK&R chapter 5.5, Character Pointers and Functions, explains pointers and shows how they are used in C. It's probably the clearest explanation of pointers ever written, and it doesn't require any understanding of hardware or assembly language (though that would help). I remember reading those three pages over and over and experimenting with the code until I got it. I probably spent several days studying the pointer chapter back when I was a teenager. The light bulb eventually went on and C pointers made sense -- until learning C my programming experience was mainly with time-shared BASIC. The stepwise refinement of an indexed array version of strcpy() to a pointer-based version is a masterpiece of programming writing -- I still refer programmers I am mentoring to that chapter. Finishing the strcpy() example with the one-liner while (*s++ = *t++) ; the authors write "Although this may seem cryptic at first sight, the notational convenience is considerable, and the idiom should be mastered, because you will see it frequently in C programs." I've found that programmers either get that line of code or they don't, and those who don't haven't mastered their craft.
- eropple 15y agoGetting it or not is one thing, but I'd advocate keelhauling anyone who wrote that sort of thing in production. The "notational convenience" is more obnoxious than anything. But, then, I'm not particularly a fan of terseness for the sake of being terse.
- gregjor 15y agoI'm not a fan of wordiness for the sake of being wordy. If you think the code is terse just to show off you are missing the point. There's a difference between writing obscure code and writing concise idiomatic code -- see "The Elements of Programming Style" by Kernighan and Plauger. I'd rather Kernighan, Ritchie, Thompson, Pike, et al. write my production code than someone who thinks C pointer idioms are a punishable offense. "That sort of thing" has been in production in the C libraries, the UNIX kernel, and all of the brilliant utilities that make up UNIX for over 30 years. It's also very much in production code at Google. You might want to read Paul Graham's thoughts on succinct code at http://www.paulgraham.com/power.html http://www.paulgraham.com/power.html and Rob Pike's "Notes On Programming in C" at http://doc.cat-v.org/bell_labs/pikestyle http://doc.cat-v.org/bell_labs/pikestyle.
- deleted 15y ago[deleted]
- cturner 15y agoI never really understood why they didn't grasp pointers The root of the problem is the language designers' loose use of star. "star something" is contained in a phrase that means one thing at declaration, "star something" has a different meaning the rest of the time. #include <stdio.h> void eg(int i) { int *j = &i; // "huh? Put the address of i into *j?" *j = *j + 1; printf("%d\n", *j); } int main() { eg(4); } With more detail. In the line.. int *var = something; .. the system assigns to the pointer. Yet in.. *var = 6; .. it assigns to the contents of the pointer. Common usage creates further room for confusion: int *var; // <- this is what people write int* var; // <- instead of this If they'd made the syntax ".int var", and then used * solely for dereferencing, people wouldn't have these problems learning pointers. Consider #include <stdio.h> void eg(int i) { .int j = &i; *j = *j + 1; printf("%d\n", *j); } int main() { eg(4); } Further confusion comes from (1) special arrangements around string declaration and (2) printf use of %s to expect a string pointer when %d and %f expects (non-pointer) simple int and simple float. char* something = "huh? so now this does goe into *something?";
- endgame 15y agoIf you remember that the experiment here was to make declaration follow use, it makes sense. I consider it a failed experiment, but it does make sense.
- deleted 15y ago[deleted]
- atakan_gurkan 15y agoTo avoid this sort of thing, I use: #include <stdio.h> void eg(int i) { int *j; // "j is a pointer and (hence) *j is an int" j = &i; // "Put the address of i into *j? Yup" *j = *j + 1; printf("%d\n", *j); } int main() { eg(4); } Perhaps this is because I am just used to it, but I really see very little room for confusion here. The common usage avoids confusion, if you do not insist on assignment at the time of declaration. To address your second confusion, just keep in mind that strings are char arrays and an array's name is actually a pointer. Again, I find this very straightforward.
- Goladus 15y agoI can't speak for your friends, but while I had zero problems with pointers conceptually, I still had trouble using them in C. The problem wasn't the simple case of declaring a pointer and taking its reference, the difficulty came when the programs got complex and required agreement between function declarations, actual parameters in calls, and use within the functions.
- adestefan 15y agoMainly because variable declarations are "backwards" in C. People try to read code left to right, but C declarations should be read right to left. Pile one things like the dual use of the static keyword, typedefs, and having multiple consts in a declaration figuring out the type of a variable can be a real chore. Dan Saks has a great article that hits on just the issues with const. http://dansaks.com/articles/1998-06%20Placing%20const%20in%20Declarations.pdf http://dansaks.com/articles/1998-06%20Placing%20const%20in%2...
- sp332 15y agoOr the classic "clockwise spiral rule" http://c-faq.com/decl/spiral.anderson.html http://c-faq.com/decl/spiral.anderson.html :)
- zedshaw 15y agoYes, actually people are deathly afraid of C thanks to other language inventor's excellent marketing against it. There's a few things that you need to really nail to be good at C, and they're difficult things, but it's not "dangerous" like people keep claiming.
- irahul 15y agoC is difficult, yes. Dangerous - I don't know in what sense. I manage to get more exceptions in my Python, Ruby code, owing to undefined variables or incorrect types, than I get segfaults in C. The main issue with C is it takes some time before you are ready to take it head on. An experienced C programmers would have his repertoire of generic data structures library with time complexity guarantees (programs without hashes, expandable lists and operations on them are a pain), will know how to properly use function pointers to do that dependency injection thing other programmers are raving about, separate interface from implementation, know the build environment, know how to use structures and function pointer to build abstractions etc. But before that, C takes much work to produce little. For someone starting programming, the learning curve is steep. Or more like, the gratification is really, really delayed. It takes some time before he can take on a real world project(it does in the high level languages as well, but the initial progress is faster).
- praptak 15y ago"I manage to get more exceptions in my Python, Ruby code, owing to undefined variables or incorrect types, than I get segfaults in C." What happens when you don't get a clean segfault is what got C the "dangerous" reputation.
- roundsquare 15y agoIt was for a while with me. I was a more "mathy" CS major which meant that languages that exposed what the computer was doing were more opaque to me... but I'm not sure that I ever considered it "scary and evil."
- protomyth 15y agoGiven how many people freak out about retain/release memory management in Objective-C, it seems that C, pointers, and manual memory management is gotta be a lot scarier.
- neutronicus 15y agoC's scheme is much easier for me than objective-C's, mainly because of autorelease.
- udoprog 15y agoI haven't perceived that people think C is significantly scary (or evil). There are however many compelling reasons not too choose C in the present RAD/Web/Cloud/Solution Business world.
- nhebb 15y ago> Do people really think C is some mysterious, inscrutable language? Yes, I do. But it's not because of the language itself. It's trying to figure out what you can do with it after you grasp the fundamentals. I taught myself C using K&R a long time ago, but I never did anything with it. At the time I figured there were two paths I could progress along - UI related (e.g., a Windows app) or systems related (something Unixy). Both paths presented large hurdles. Nothing insurmountable, but I wasn't a programmer at the time - just doing it for my own edification. I always thought it would be nice if there was a second level book that took you from post-basics to writing something useful.
- rpearl 15y agoThat's nothing to do with C as a language, but rather to do with relevant APIs, which can be difficult to read at times.
- wvoq 15y agoI don't intend to argue so much as to offer a data point: I suspect that most folks on this site learned C or something C-like early on, and have internalized its modus operandi. I have been learning C recently from a background of functional programming, and I find it scary and evil. FWIW, I enjoy programming very much, and have built some non-trivial stuff in several languages. Still, I found C extremely taxing. Not in the sense that I felt it was beyond me, but in that I was fighting or recoiling from the language at practically every turn. In what follows, I am acutely aware that I am nowhere near fully fluent in C yet, and am writing only to offer the first impressions of a student. Nevertheless, in that time I have been able to draw on the advice of several "experienced colleagues", as K&R urge. In that sense, if I misstate the facts, I will be repeating the misconceptions of people who have objectively spent an awful lot of time writing C. I would be glad to be corrected on any point, but I'd also find that kind of symptomatic of the issues I have with C. Firstly, C is incredibly stateful. I would be glad to learn that I am just Doing It Wrong, but there seem to be no obvious way around stateful manipulations as a way of life. Take, for instance, the fact that arrays are essentially second-class citizens and must be stuffed into functions as (pointers to) extra parameters in order to capture the "function's" "output". I am breaking out the scare quotes here since it is an abuse of vocabulary to refer to a procedure that communicates with the world by modifying its inputs as a function. If you have not cut your teeth on it, it seems almost obscurantist. If I want to multiply A by x and store the result in b, I want to write b = matrixProduct(A,x); not matrixProduct(b, A, x); as I must in C. I go back and forth over whether this is a deliberate and worthwhile performance tradeoff or just myopic design[1], but I don't want to have to settle for this in code I read every day. There is also a kind of bureaucratic spirit in much C code, resulting from the fact that one must attend so closely to the how of computation rather than the what. In some contexts, like when you're doing distributed simulations that may run for days and performance is at an absolute premium, this emphasis may be appropriate. In most contexts, however, one finds oneself implementing and reimplementing standard operations by hand. Why should it take four lines to sum an array? One of the most alarming symptoms of this style can be witnessed by watching an experienced C programmer read code. Old hands don't read lines, they scan an entire section of a page at a time. I was awed by this ability until I realized that it is possible only because each line of C does so little. I recall someone (probably in an HN comment) describing the "rhythm" of reading C code. That, to me, is not an encouraging sign. Then there is, of course, the penance of debugging segfaults and space leaks. What happens when you declare 10 pointers and allocate 9 of them? No one knows, because C doesn't know either. It's up to the compiler. Towers of Hanoi, nasal demons, &c. Even with the help of with smart and experienced people, I've never spent so much time diagnosing such trivial, silent runtime errors. Yes, I know it's that way for a reason, but that reason is not legibility or ease of understanding. At end, C has performance and a relatively (but not exceptionally) compact semantics. The importance of cycle-squeezing is becoming less of a consideration daily, for reasons well-rehearsed on this site and elsewhere. As for C's semantics, I'd much rather spend my time thinking about the transformations I want to map over my data than orchestrating von Neumann machines to carry those transformations out. If your model of computation is something other than register machines, it's not quite cricket to describe the implementation as magic. ----------------------------- [1]I'd like to qualify that remark in two ways. Firstly, I certainly recognize the brilliance of K&R for working C from the raw conceptual materials of the time. Secondly language designers in 1969 did not have the benefit of the last 40 years' of object lessons in readability. There are many potential languages--points in language space, if you will--that are semantically identical or near-identical but much more readable than the ansi standard. For an example given by Kernighan himself, postfixing the dereference operator would have done miracles for legibility. Ultimately, a lot of more or less arbitrary choices were made early on and now it's too late to correct them.
- tomrod 15y agoI've programmed now for 5 years, and I find C hard. But then, I've mainly programmed in C# and Python.