17 ms·
Deep C and C++ (2011)
- aidenn0 13y agoHeh, and they didn't even get into the aliasing rules. In embedded software, life would be a lot easier if I could hit every engineer who wants to type-pun without a union in the head with the ISO standard. For this reason, a lot of compilers have options to not strictly enforce the aliasing rules [edit] Also C and C++ are both permitted to reorder structs, it's just that they don't because that's the easiest way to follow the standard.
- 0x09 13y ago> Also C and C++ are both permitted to reorder structs, it's just that they don't because that's the easiest way to follow the standard. Is that feasible? Doing so would require that the order of the member addresses not correspond to their layout in memory.
- pjmlp 13y agoAs long as the code is fully visible and compiled by the same compiler, then yes.
- caf 13y agoNo, in C struct members must be allocated in the order in which they are declared. C99 §6.2.5 says: A structure type describes a sequentially allocated nonempty set of member objects (and, in certain circumstances, an incomplete array), each of which has an optionally specified name and possibly distinct type. and §6.5.8 says: If the objects pointed to are members of the same aggregate object, pointers to structure members declared later compare greater than pointers to members declared earlier in the structure,…
- mansr 13y agoWhat the language standard does not specify (and is very explicit about not doing) is padding between struct members, if any. However, the ABI spec for the compilation target details exactly how a struct must be laid out. If this were not the case, libraries could not work.
- klodolph 13y agoC is not allowed to reorder structs. There's a section in the C standard, n1516 page 113 (section 6.7.2.1 paragraph 15) > Within a structure object, the non-bit-field members and the units in which bit-fields reside have addresses that increase in the order which they are declared.
- jmgao 13y agoAs mentioned by others, C does not allow reordering of members in structs. However, C++ does! §9.2.12 says: Nonstatic data members of a (non-union) class declared without an intervening access-specifier are allocated so that later members have higher addresses within a class object. The order of allocation of nonstatic data members separated by an access-specifier is unspecified (11.1) This means, that under a strict reading, even the following struct can have its members reordered: struct foo { int a; public: int b; }
- ben0x539 13y agoDid this change in C++11 or does this wording mean the same thing? It's not clear to me that the implicitly public a is of a different access control than the explicitly public b according to the following wording: > Nonstatic data members of a (non-union) class with the same access control (Clause 11) are allocated so that later members have higher addresses within a class object. The order of allocation of non-static data members with different access control is unspecified (11).
- aidenn0 13y agoThat's what I was thinking of. Thanks.
- aDevilInMe 13y ago"In embedded software, life would be a lot easier if I could hit every engineer who wants to type-pun without a union in the head with the ISO standard." Is that the same standard that says it is illegal to write to one entry and read from another in a union* ? * Note : special situation of identical fields in a structure
- mansr 13y agoThe C99 standard explicitly says type punning through a union is allowed. This is clarified in TC3 (2007) by the addition of this note in section 6.5.2.3: If the member used to access the contents of a union object is not the same as the member last used to store a value in the object, the appropriate part of the object representation of the value is reinterpreted as an object representation in the new type as described in 6.2.6 (a process sometimes called "type punning"). This might be a trap representation.
- aDevilInMe 13y agoThanks, I was not aware that this was corrected in a later edition.
- Too 13y agoEmbedded C developers can produce very, ehum, 'interesting' code. They usually come from electronics engineering and think in terms of registers and memory instead of an abstract machine. I've seen code that actually relies on two arrays being defined in order and thus can be indexed from only the first array but with a calculated offset. This is outside of a struct... Just type casting a struct to a char-pointer and dumping it straight out on the network or to persistent storage is code you see every day.
- raverbashing 13y agoIt's a good discussion of the behind the curtains working of compilers But I'm very aware of "smart code" and we shouldn't be writing code that relies on the details (especially ones that might change between compilers)
- greyfade 13y agoBut we should certainly be aware both of what the language requires of the compiler and of potential pitfalls.
- waps 13y agoThe problem there is that while compilers have been getting better, they're nowhere near beating good programmers (yet ?). Languages other than C/C++ get in the programmer's way and prevent them from using "maximum" cleverness, and that means the best java/c# programs are simply always going to be slower than the best c/c++ programs.
- dllthomas 13y agoThat's true on balance, which is why C/C++ is still typically faster than managed languages. In many particular cases it's not true, however. Consider "register" or "inline" directives, which have been advisory for a long time.
- zvrba 13y ago> Why do professional programmers write code like this? Because we 1) for some reason or another we _must_ use C or C++, 2) we're coding for a single CPU platform, and 3) we need to get the friggin' job done in this century.
- rcfox 13y agoPrevious discussion: https://news.ycombinator.com/item?id=3093323 https://news.ycombinator.com/item?id=3093323
- yngccc 13y agoThe girl forgot to mention exception safety on the class A slide, no hire.
- hamidr 13y agolol yeah But she is a C programmer you know ? ;)
- jmgao 13y agoThe constructor also wasn't tagged explicit.
- deleted 13y ago[deleted]
- kirab 13y agoIf B() is noexcept then A() is actually exception safe. The only thing which could happen would be bad_alloc but then v does not have to be deleted any more.
- zvrba 13y agoRight, like what happens with the memory allocated for px in situation like below, if new ClassY throws? A::A() : px(new ClassX), py(new ClassY) { }
- hacknat 13y agoI'm not so jaded as to think that deep language understanding isn't a useful or good thing, and I'd like to think I have some myself. However, deep language understanding is not what separates the great engineers from the good ones. In an interview, I would much rather hear a person say something about a statically declared variable with no initialization being poor code to leave behind for the next person than some arcana about the standard.
- thepicard 13y agoArguably if people have such strong understanding of things they will be better programmers too. I would prefer the person who knew what they were doing, because they also know _why_ weird things are weird, and have a better real understanding of what to do and not do. A person who just knows it's "bad code"--but not why--is almost certainly going to leave other bad code from lack of understanding. To pull an example from the slides, the virtual destructor: making that class virtual when it shouldn't is a waste of CPU cycles _and_ bad documentation for future developers.
- easytiger 13y agoIn c and c++ understanding these things can save you 1 day a week on average.
- pjmlp 13y agoI would say even more than that. C and C++ can make someone loose days to track down issues, in this day and age, where teams are distributed with lots of offshoring and various skill levels across development sites. My last C++ project was in 2006, since then I have only used C++ outside work. At work our focus has been in JVM and .NET languages. I don't miss playing the C++ fireman expert role that has to fix a stability problem created by someone in the other side of the planet.
- easytiger 13y agoYea actually even last week I have spent and entire day trying to bend a c++ library to my will due to errant assumptions and such. All part of the long and painful learning process!
- pacaro 13y agoI've been a C developer (among other things) for about 20 years or so, but I've always described my C++ skills as being "in the C with objects" range, I might have to change that to being "nearly in the C with objects" range.
- xerophtye 13y agoYep, with C and C++ , you can't really say you are an expert.
- hamidr 13y agoI wonder how's salary comparing to other programming languages?
- pjmlp 13y agoThat is the same with any language. An expert should not only know the language as defined by the standard or canonical implementation, but also the majority of implementations for the said language and consequent deviations from the official language semantics. Ergo, no one is actually a real expert in a specific language.
- xradionut 13y agoKay is an expert in Smalltalk and Wirth is an expert in Oberon. Stroustrup is an expert at nailing legs to a dog and calling it an octopus.
- pjmlp 13y ago> Kay is an expert in Smalltalk and Wirth is an expert in Oberon. No, they are experts on the implementations they created, not on the other ones that were created.
- eruditely 13y agoThat standard is too arbitrary and stringent.
- chipsy 13y agoPeople complain loudly about gotchas in JS, but when you look at what C++ programmers have to contend with...
- hamidr 13y agoAt least C++(11) is a (better) statically typed language :) Although, This isn't even half of it! thanks god the girl didn't know anything about templates.
- dllthomas 13y agoTemplates are a horrid syntax for an okay functional, compile-time language. They can be useful - in quite a few ways an improvement on C macros. I say this as someone who's done quite a bit of C and C++, and am currently working mostly happily in C at work and Haskell on my side project.
- obiterdictum 13y agoConversely, JS programmers I complain about JS gotchas about contend that "once you learn all those horrible gotchas, it's a great language". Even C++ programmers, at least the ones that had good fortune to have time away from C++, agree that C++ gotchas are unforgivable. But in general, C++ and JS communities have the biggest cases of Stockholm Syndrome I've seen. Disclaimer: I'm a recovering C++ programmer.
- humanrebar 13y agoFor the niches that JS fills, a clear language with few pitfalls would be best. C++ has a different niche. On top of that, everyone acknowledges the warts of C++, but they're largely necessary for either backward compatibility or performance reasons.
- deckiedan 13y agoIt is interesting looking at the 'deep' issues of programming languages. This kind of ties in with the "Don't ask me maths questions..." post a few days ago. There really is a lot more to programming than just algorithms, UI design or syntax.
- raverbashing 13y agoYes, this worries me. Especially today some people think "great programmers" are the ones who knows all the "fashionable" tools and frameworks, wants to abstract everything (god help him if he install vim in his test environment without a fab file that configures chef) and maybe worships Uncle Bob Knowing how to use Redis is cool, do you know what's even cooler? Being able to write it (or at least knowing how it works more or less)
- dmak 13y agoI'll rather pay an artist to paint me a nice piece using store bought paint than making his/her own paint. Each programmer is great in their own right.
- EliRivers 13y agoEach programmer is great in their own right. Some of them, however, are terrible at programming.
- dagw 13y agoI'll rather pay an artist to paint me a nice piece using store bought paint than making his/her own paint. That's fine if you just need a nice picture to hang on your wall, but probably won't work if you want a genre defining piece that that redefines how artists think about the color blue.
- Ygg2 13y agoEven better is getting a programmer that knows enough about making X to not attempt to implement it. Anyway the programming is such a multi-dimensional evaluation problem that you're just as wrong as you are right. Think about it - there are so many things programmer SHOULD KNOW it isn't possible to know them all. Let's name them some of them - good architecture style, good API writing skills, good code writing style, good documentation style, company's internal workflow with all its nuances, compiler standards, compiler optimization, non-standard compiler behavior, version control system API, version control innards, database system, file system, low level operating system implementation, kernel innards, non-standard OS behavior, hardware knowledge, driver knowledge, non-standard hardware behavior, hardware compatibility, software-hardware compatibility, etc. (This doesn't cover assembler knowledge, binary represntation of important formats). You simply have to choose to not learn everything about certain system to be good at other things.
- loup-vaillant 13y agoThis was good, but… Hermione (I'm sure that's her) rates her C++ knowledge at 4-5, and Stroustrup himself at 7!? Bullshit. Either they are poorly calibrated, or they are displaying false modesty. Sure, they probably still have plenty to learn about C++, but come on, Hermione is already at the top 97% in terms of language lawyering. Wanting to be stronger is good. Not realizing you're already quite strong is not so good.
- banachtarski 13y agoIt's all relative. I would consider a 10 somebody who could write the C++ compiler without guidance for example. And probably give myself a 4 as a result.
- Negitivefrags 13y agoWould you only consider someone's knowledge of Python a 10 if they could write a Python interpreter without guidance?
- smnrchrds 13y agoI will give the creators of PonyORM a 10 as well. http://stackoverflow.com/questions/16115713/how-pony-orm-does-its-tricks http://stackoverflow.com/questions/16115713/how-pony-orm-doe...
- Romoku 13y agoIt's really quite interesting that they build the queries from the AST. To contrast C# generates the Sql for Linq to Sql by building up an expression tree using the IQueryable interface. This simplifies step one of the Pony ORM author's answer.
- banachtarski 13y agoMy point is the scale is absolute. Somebody who rates themselves a 9 on C++ knowledge probably doesn't realize how much there truly is to know. Sort of a corollary to the dunning-krueger effect.
- kirab 13y agoI got really annoyed by those stupid and ever-repeating mean comments like "do you want another ice cream?"
- puredemo 13y agoglad it wasn't just me.
- mrottenkolber 13y agoI also found this very awkward. Especially because the author created the character he subsequently demolished. While I can follow most of the C problems, C++ has never interested me. As as a Common Lisp programmer, all of this seems quite demented. By reading the slides I have learned about some interesting optimization concepts, and wondered how CL compilers do it. But honestly for 99% of my Job I couldn't imagine using something like C. Edit:grammar.
- cubsink 13y agoErm, sure some things are about knowlegde and having more skilled people are better. However, who the fuck would begin to talk about different standards on the simple program at the beginning? It is all about the question, and the question was asked in a poor way making the candidate unsure on what you want to know and will most probably have a simple answer. I personally hate questions like that because it's stupid to ask them. The point of asking a question is to get as a good answer as possible. Then, please don't ask vague questions and be waiting for the long, detailed answer.
- theCricketer 13y agoA college student in CS here. I'm always impressed by people with deep understanding of programming language internals and try to pick up as much about programming language internal workings and compilers as I can. How does one get really good at this? Is it by spending a lot of time programming and building stuff? Is it by reading books/blogs/articles about programming languages? Any recommendations for such resources?
- kamaal 13y agoOne way is as you said is by spending a lot of time programming and building stuff. The slide deck says, the only way is the experience. You need to read and learn endlessly over the years. Like you I hope there was one book, that does this. Makes a nice idea for a community project. Compiling such massive wisdom into a book can't be done by a person alone. Currently its a bit like alchemy, looks very little chemistry and much more magic. And to learn there are hardly any resources beyond your regular C books, which more or less keep talking of the same things.
- RogerL 13y agoI always found it extremely useful to 1) learn to program in assembly 2) inspect the assembly generated from your compiler 3) trace a call all the way from user land down into the kernel, and back up 4) don't forget networks. Whether that means a single wire instrumented with a 'scope, or a network switch instrumented with wireshark, knowing how data gets around is important. Until you can do that on your platform, you don't really understand it (which is fine for many jobs out there, I'm just addressing the question of how to learn it). I suspect the shortest and best path is to write your own (toy/emulator) assembler and compiler, and to do some embedded work with no OS. That'll at least expose you to all the various issues; you might not implement register allocation well (or at all), but you'll have had to think about it and the implications (example: passing function parameters on the stack vs in registers). That's one of the advantages of a University education to my way of thinking. You will be put through all these paces if it isn't just a Java accreditation program. There are good books documenting, say, the Windows or Linux internals, so you can gain a good understanding of things like virtual memory, device drivers and so on. It is not as hard as it might seem. This is all basic information, one fact built on top of another. I have no idea how the ARM pipeline works, but that doesn't worry me. I know what pipelines are, some of the tradeoffs they have, and if I need to get down and dirty with a cute little ARM processor I'll know what I need to learn. You can feel sort of overwhelmed if you try to think how pressing on these keys get turned into truetype fonts on a graphical screen, and then sent across the internet to anyone bored enough to read my ramblings, while at the same time my computer updates the clock, checks my mail, and does a dozen other things, but piece by piece it is all discrete, well contained, and completely understandable. Reading Stroustrup is pretty much mandatory to understand C++. I personally wouldn't bother with the standards (other than a brief go-over); so much of the code in those slides are just things you should never, ever program. Which is to say I disagree with the slides in large measure; it's almost suspicious to have some of that knowledge! Either your coworkers are writing truly atrocious code, or you are spending time learning corners of the language which is time that almost certainly could be better spent elsewhere, such as learning about memory mapped files or something. As others have said, knowing where the boundaries of where undefined behavior lies is important, but knowing how to avoid straying even close to that territory is far more important (always initialize variables. Even static ones! You are going to cost some sorry bastard half a day of debugging when they erroneously think the problem in the code is an uninitiated variable and keep chasing that until they finally figure it out)
- shurcooL 13y agoKnowledge of the language is a big factor, but it's far from being the only one. How fast one is able to create things is an example of another important factor. There are many more.
- glormph 13y agoI only know python well and am looking for another language to learn. C was on the shortlist, but after this, crikey. At least I now know it's not going to be an easy ride.
- userulluipeste 13y agoI found the original ANSI C to be more straightforward, and many times after I was asking myself "why was this done in this way" I only realized that I would have ended up with the same way of doing things - e.g. that the stack arrays should just skip the "pointing" memory, and things like that. What you saw in the presentation are mostly just later complications that popped up from the attempt to improve the manner of approach while keeping the entire thing speedy and backward-compatible. Do you think this is too much? Take a look at C++11 and marvel at the quantity of language hacks there!
- nraynaud 13y agothis has nothing to do with understanding but more with memory. What's drowning people in C and even more in C++ is not the logic of the language, but the sheer number of tricky concepts and the pure accumulation of information (it is reflected on the size of the specs). There is also the fact that very often non-specified behavior, or implementation dependent or everything else that is not cool does not lead to a warning, so the learning is absolutely not reinforced by the compiler. Whereas a warning/error leads to questions that leads to google and some learning; you can be stepping far in the Pampa of undefined behavior for years when someone comes with a superior attitude in your company detects it and calls you a moron in a powerpoint. And this also leads to very hard to write code sometimes, if you want to do some serious IEEE754 in C/C++ you will basically be pitting the spec of the language against the spec of numerical computation in a ring.
- rfnslyr 13y agoThis has nothing to do with understanding but more with memory. What's drowning people in C and even more in C++ is not the logic of the language, but the sheer number of tricky concepts and the pure accumulation of information (it is reflected on the size of the specs). I've been coding C++ for a few years now and it still baffles me most of the time. If I take a break from it for a bit, I have to re-learn how pointers function every time.
- kyllo 13y agoWhat's drowning people in C and even more in C++ is not the logic of the language, but the sheer number of tricky concepts and the pure accumulation of information (it is reflected on the size of the specs). I agree, and I'd add that C/C++ is a bit of a leaky abstraction layer over assembly. It aims to be portable, but true portability means that the C/C++ developer really shouldn't have to know/care what assembly instructions the compiler/linker is emitting, because all of that stuff depends on which chip architecture you're targeting. Basically, coding in C/C++ requires an intimate knowledge of how the compiler works, and sometimes even how the target chip works. C/C++ software projects of notable size oftentimes cannot be simply recompiled/linked to a different target architecture without changing things like compiler flags, the makefile, and even the application code itself. That makes it a non-portable, leaky abstraction, and dramatically increases the amount of knowledge that's required of a C/C++ developer.
- jgreen10 13y agoHow far into the presentation do I need to go for someone to mention that the quotes in the printf are not US ASCII and therefore the program would not compile?
- jheriko 13y agoseen this before. whilst its great there are degrees of respect to have for C and C++. the most productive code i have ever written generally involves me working around the constraints of the language to implement a paradigm which is missing at compile-time, or juggling macros and templates so that i can reduce boilerplate code down to a template with a macro to fill the gaps the template is too featureless to give me (vice versa, the template is there because macros aren't complete enough either). its good to understand this deep language stuff though because you can understand why C/C++ are limited. for instance the C sequence points limit the compiler in its ability to perform optimisation, as do struct layout rules and many of the other weird and wonderful specifics... what saddens me most though is that nobody has offered anything to improve C and C++ in these areas which matter most to me... its not even hard. just let the compiler order structs because most programmers don't understand struct layout rules. its not a good thing that these things are so explicitly specified for the language - its gimping the compilers, which is limiting me. also it results in pointless interview questions about sequence points.. :P
- enterx 13y agoGreat story. Deep understanding of the language used will make you do a better job. This reminds me of the story that I've run into once. The junior developer wanted to raise PHP's memory_limit parameter because his code crashed almost every time while writing big file content to the output. He didn't know what output buffering is and that he can turn it off and print the file directly to the output. :D
- praptak 13y agoA fun fact about sequence points. C++ has switched from "sequence points" to "sequenced before/sequenced after" relation. And it is not really "all" previous side-effects that are guaranteed to be visible after the sequence point but only those associated with the sequence point. In 'foo(b++, a++ && (a+b));' the sequence point introduced by the '&&' only makes the 'a' see the effect 'a++' but the 'b' might not see the 'b++' (function args are not sequenced in C nor C++).
- ridiculous_fish 13y agoRight! In fact I believe the above code invokes undefined behavior, because b may be accessed for a reason other than to determine its new value, without an intervening sequence point. Put another way, the compiler can arbitrarily interleave the subexpressions within separate arguments: foo( a() && b(), c() && d() ); The compiler is free to invoke these functions in the order a(), c(), d(), b() if it pleases.
- coldpie 13y agoWhy on Earth are you writing a statement like that in the first place?
- ben0x539 13y agoIt's probably less about writing the statement while cackling maniacally and more about recognizing that pattern in less obvious examples in existing code while reviewing it or looking for a bug, and realizing that it might be worth investigating and not just a style nitpick.
- praptak 13y agoExaggerated example to show a pattern. A (hopefully) less outrageous (but still bad!) example of the dangers of sequencing: foo(std::unique_ptr<T1>{new T1 }, std::unique_ptr<T2>{new T2 }); This one's from GotW #102.
- alok-g 13y ago
- deleted 13y ago[deleted]
- deleted 13y ago[deleted]
- deleted 13y ago[deleted]
- austinz 13y agoOoh. I remember "Dynamic-C" and its built-in support for coroutines. TI and Microchip had their own quasi-proprietary extensions to C, but I don't think I ever saw anyone go as far as Rabbit did.
- laichzeit0 13y agoSorry I deleted my original comment as I thought it might be too off-topic. Yes, Dynamic C had built-in coroutines :) I think it's hard for me to use threads now because of how convenient a single-threaded main loop with coroutines is. A lot of concurrency "problems" vanish when you realize you as the programmer are controlling the context-switching and that race conditions are implicitly not possible then. I went so far as to write my code so that it compiled in GCC and Dynamic-C to speed up development time (not needing to wait for the 2 minutes it takes to compile and reflash), which meant abandoning all those things and re-implementing them in a cross-platform way buried in a mountain of #ifdefs Although I can't remember all the details now (5 years since I touched that compiler) but I still have a lot of deep seated hatred towards it for reasons I can't remember clearly :)
- saejox 13y agoAll of the quirks listed have good reasons to exist. Except size_t, that never makes sense.
- pcwalton 13y agoI don't agree. Just a few slides in, what good is "functions don't have to return a value explicitly, even if declared as returning non-void" (a priori, I mean—not counting backwards compatibility as a reason)?
- revelation 13y agoWhat bizarre nonsense. I hope nobody thinks this level of (mis)understanding is replacement for understanding, you know, how to program. The majority of this is undefined behavior or implementation details of your compiler. If you rely on that, I don't want your code anywhere near my machine.
- pkolaczk 13y agoI think you missed the point. It is more about coder's attitude than about using (or not using) the presented examples in real code. I wouldn't like to work with a programmer than writes shitty code accidentally relying on UB, and denies every criticism by saying "it works, so what's up?".
- blueblob 13y agoI felt this way as well. On an interview why would you give a really specific answer to a really general question? I don't think it's that most people can't answer like this, rather that it's not what was asked.
- benched 13y agoI am trying to find a way to reconcile two realities. On one hand, whenever I encounter books or articles on language legalese (particularly in C and C++), it is always immediately apparent that I'm somewhat out of my depth, despite programming in C and C++ for 20 years. I can follow the reasoning, but I almost never spot the finer problems myself. On the other hand, I can and have written large, complex games that run well and appear to be just fine from the user's point of view. I can seemingly write reams of code without ever thinking of such issues, except when they trip up the compiler or cause detectable bugs. I find I very, very seldom need to think of the lawyerly issues at work, or in personal projects, and to my knowledge, nobody has suffered materially for it. (Granted, I am writing games and not NASA software.) Whenever these types of issues come up, I always think: "Wow, I know less than I thought. This seems serious?" And yet I never seem to see real-world consequences. This seems strange to me.
- chr13 13y agoI haven't seen these tricks come into play when solving real problems at ALL. Not saying you should not know the language, but better to have problem-solving skills than rot the standard. The bit about leaving a new line after main tells me she really has memorized the standard.
- dllthomas 13y agoIt's not about tricks, it's about precisely understanding the mechanics of the language. This can be exploited to craft tricks, which is occasionally important. It can also be exploited to avoid gotchas, which is usually important. It can also be exploited to better and more quickly understand what some behavior means when things aren't working as expected, which is always important.
- chr13 13y agoI guess it depends on what you consider "real problems". One can always write good and efficient code by following what he/she knows is the defined behavior. Just found weird that some things related to standards were given more importance whereas problem solving is the key while writing any program.
- dllthomas 13y agoWell, I'm currently being paid to write C day to day, so it's solving someone's real-enough problem that they're willing to part with money. I described roughly how I see my comprehension of the language reflected in my work.
- brohee 13y agoThe girl spewing some bullshit may lead to an interview ended early. Clearly bright, but not as bright as she think she actually is... Come back in a few years with a bit more humility... Hard to decide if the other guy is bad or inexperienced without a resume... "If you compile in debug mode the runtime might try to be helpful and memset your stack memory to 0" This is a retarded explanation (pages are set to 0 when they are recycled by the OS so you don't end up having data from dead processes mapped in your memory, with all the security implications). Also, actually randomizing memory in a debug context would actually be more helpful to trigger those initialization bugs... People that think they know everything are a lot more dangerous than people actually aware of their limitation and safely working within them.
- susi22 13y agoMS Visual C initializes it to 0xCCCC so it's easy to spot. It helped me find a few errors.
- quasque 13y agoAlso 0xCC is the breakpoint opcode (INT3) on x86 architecture, so if the program were to start executing at that point, the debugger would be notified (or probably an immediate application crash if no debugger attached).
- RogerL 13y agoOkay, you are assuming an Intel architecture? Plenty of embedded environments don't have OSes, let alone pages or virtual memory. IOW, I've worked in environments where, yes, the value in memory is based on what the compiler does in debug mode, not what the OS might be doing. I'd say the girl's answer is, while not exhaustive, certainly correct. Without more context, we don't know why the value was 0.
- brohee 13y agoYou have printf, and the interviewer says "on my machine, I actually get 1, then 2, then 3". Those two hint very strongly at a general purpose computer, thus paging etc. What really annoyed me is the suggestion that zeroing is more helpful than randomization in a debug context. Randomizing everything not defined by the standard is a good way to trigger lots of bugs based on false assumptions...
- dllthomas 13y agoRegarding padding, with GCC at least it's not (precisely) word size that it optimizes for, but alignment constraints of the particular members. A short will be bumped to a multiple of 2, an __int128 will be bumped to a multiple of 16. The alignment restriction of an entire struct is the largest alignment of any member. This certainly has the intent and consequence of more aligned loads.
- dllthomas 13y agoI'm not sure "provide only one way of doing things" is a core principle of C. It at least seems to have fallen to "type less" in several cases: i = i + 1; i += 1; i++; ++i; a[i] *(a + i) a->foo (*a).foo
- humanrebar 13y agoYou left out: i[a]
- dllthomas 13y agoI considered it, but decided it would be more noise than substance in this particular list. I do like that pun, though.
- talles 13y agoDespite all the discussion of the 'relevantness' of knowing a language in a so deep level, I think this presentation is genius.
- rfv 13y agoI wonder what a linux kernel developer would have to say about these slides. How many of these features/quirks are they finding useful in their day to day job.
- agentultra 13y agoI love this presentation. It led me to read Expert C Programming [1] by Peter Van Der Linden. My knowledge of C had vastly improved after reading that book (and subsequently C++). Even if you're not a C programmer I would recommend the book as the anecdotes alone are worth reading for the questions that it encourages you to ask. I've since come to believe that reading the specifications and having the attention necessary to delve into these kinds of details and ask the right questions is important for mastery. It seems to me that learning 1 - 2 languages to this level of detail is worthwhile. I've been thinking of cutting back the number of languages I, "know," down to just those for which I am familiar with the specifications and how they're compiled, assembled, etc. Everything else is superficial. Sometimes all you need is just a cursory knowledge to get something done and the ends justify those means. However if you really love your craft then mastery should be the goal, no? It seems to be the difference between, "getting something working," and, "pushing the boundaries of what is possible." [1] http://www.amazon.ca/Expert-Programming-Peter-van-Linden/dp/0131774298 http://www.amazon.ca/Expert-Programming-Peter-van-Linden/dp/...
- sanderjd 13y agoIt's wonderfully frustrating that there is truly so much to learn that even the study of programming languages, which is an incredibly tiny field relative to the whole of human knowledge, it is still necessary to make depth vs. breadth trade-offs. I find your choice to focus more on depth appealing, but almost immediately feel a sense of loss for all the breadth such a focus would require giving up. I think a better balance may be to master things that are widely relevant at depth, while giving less focus to things that are very specific. Put another way: depth for "essence", breadth for "accident". Of the items on slide 181 of the presentation, only calling conventions, memory model, and probably optimization seem like "essence" to me, ie. every program you ever write in any language will benefit from deep knowledge of those topics. The rest of the items are somewhat arbitrary and very specific to the particular history of the C language itself.
- agentultra 13y agoIt boils down to learning a handful of languages enough that you can make some meaningful contributions or a single language deep enough that you can have a meaningful discussion. Neither approach forgoes learning fundamental theory. I equate learning to master C like learning to master a particular instrument like the violin; it requires knowledge of the instrument's construction, the physics of how it produces sound, and a host of other details that must be mastered before one can really make it sing. I can study music theory for years and it won't help me play the violin well. It will make composition easier and assist me as I adapt myself to the instrument. However one still has to master the instrument and I see the two being complementary and distinct skills. The metaphor holds together when you start thinking about the breadth of languages available. For example, my primary instrument is guitar. I've been playing for years and have a good grasp of it. However I recently took up the violin so that I could learn to fiddle and play some bluegrass and Irish folk tunes. I still can't play a single tune well on the violin but my knowledge of string instruments and music theory is certainly making my adoption faster than someone who is starting from the very beginning. However one must be careful with breadth. I could try to learn to play the mandolin after I've "finished," with the violin. And perhaps a banjo after that. However mastery requires a deep, intimate knowledge: you have to spend time with an instrument, learn its quirks, and practice with it every day. Even the best guitar players practice every day. You don't have enough time in this world to master every stringed instrument. Harder still is the transition to a completely different class of instrument. Mastering drums and guitar is not impossible but rather difficult as knowledge of one doesn't offer much in learning about the other. Learning C is one thing but learning Common Lisp is learning an entirely different model of computation. Having a grasp of the fundamental theories will help some here but nothing you know about C compilers will help you to understand CL (and vice versa). So be even more suspicious of the depth of a programmer's knowledge if they list more than a few languages on their resume if those languages span entire classes of computational models. And I don't think there's enough time in this world for even a very competent programmer to say they are a master of more than one or two languages. Update Added a paragraph on computational models and expanded the instrument metaphor.
- hardwaresofton 13y agoThis slideset has shamed me. I definitely don't know enough about any of the languages I use on a daily basis. I also thought I knew about C/C++.
- skandl 13y agoInformative and thought-provoking presentation, but I think the mock interview format is a disservice, as with it comes individual ideas of what a good or useful interview is like.
- sanskritabelt 13y agoYou know if someone's asking me these kinds of questions in an interview it's the sign that something's deeply dysfunctional on the team and there's been some kind of past trauma that makes them feel the need to ask. That or they're assholes. Either way, walk.
- sanskritabelt 13y agoGot to slide 413. Get a freaking hobby or something. Maybe a dog. Go outside a little bit.
- NAFV_P 13y agoI signed up with HN to get articles related to C, yet they're about as common as hens teeth. I've just executed a word search on this comments page: 18 instances of "static", but no mention of "volatile" or "extern", which is the same situation in several textbooks on C. The article mentioned looking at the assembler output of a program, but didn't give any hints on where to learn some assembly.
- pessimizer 13y agoI've noticed that the internet contains information about various assembly languages. I would suggest googling for their manuals.
- NAFV_P 13y agoIt is tutorials that are required for learning, manuals are for people who are already proficient.
- xradionut 13y agoYou need to learn the history of HN and realize that Lisp is the original hacker language. As for assembly, there's been several lists of "free" computer books post that have included assembly tutorials.
- NAFV_P 13y ago"You need to learn the history of HN and realize that Lisp is the original hacker language." That's fairly common knowledge, I've been coding for eighteen months and I learned that "fact" months ago. "As for assembly, there's been several lists of "free" computer books post that have included assembly tutorials." I haven't mentioned what assembly I wish to learn. A lot of the assembly tutorials I have found on the web talk about x86 assembly, yet my processor is 64-bit. I'm quite sure that the principles extend easily from one register size to another, but I have no experience at all in assembly.
- blt 13y ago
- Suncho 13y agoMost of the C stuff here is pretty good, but some of the C++ information is a little questionable. Even the "good programmer" exhibits a few common misconceptions about inheritance and virtual destructors. Here's the text from slide 348: "What is the point of having a virtual destructor on a class like this? There are no virtual functions so it does not make sense to inherit from it. I know that there are programmers who do inherit from non-virtual classes, but I suspect they have misunderstood a key concept of object orientation. I suggest you remove the virtual specifier from the destructor, it indicates that the class is designed to be used as a base class - while it obviously is not." She's right that the class described on the slide probably shouldn't have a virtual destructor. A base class should have a virtual destructor if and only if objects of its derived class are to be deleted through base class pointers. The following four statements are wrong: 1. A class with other virtual functions should have a virtual destructor. 2. A class without other virtual functions should not have a virtual destructor. 3. A class designed to be a base class should have a virtual destructor. 4. You shouldn't inherit from classes that don't have virtual functions. It's a narrow-minded to say that programmers who inherit from "non-virtual" classes have "misunderstood a key concept of object orientation." Which key concept is that, by the way? Object orientation isn't the be all and end all of C++. There are reasons to use inheritance that have nothing to do with run-time polymorphism. Maybe you just want to reduce redundancy and organize your data types in terms of each other. Another gripe is that on slide 369, she says: "When I see bald pointers in C++ it is usually a bad sign." Naked pointers should usually be avoided for memory management. That's true. But they make great iterators, and they're useful, along with references, for passing objects to functions. On the other hand, seeing the keywords "new" and "delete" in code is usually a bad sign. Resources (not just memory) should be managed by resource management classes. If you try to do it manually, especially in the presence of exceptions and concurrency, it's very easy to cause an inadvertent resource leak.
- NAFV_P 13y ago"On the other hand, seeing the keywords "new" and "delete" in code is usually a bad sign." I thought those two keywords were intended to replace the basic memory allocation functions found in stdlib.h. What are the alternatives?
- bshanks 13y agoI think this presentation is interesting from a programming language design point of view; if you were designing a new language, this presentation highlights various 'gotchas' in C and C++ that might be the sort of thing you would try to avoid creating in your new language. Many of these fall under the heading of opportunities to apply the Pythonic design criterion "refuse the temptation to guess": 1) in C, according to one of the comments, it was claimed (i didn't check) that if you declare your own printf with the wrong signature, it will still be linked to the printf in the std library, but will crash at runtime, e.g. "void printf( int x, int y); main() {int a=42, b=99; printf( a, b);}" will apparently crash. -- A new programming language might want to throw a compile-time error in such a case (as C++ apparently does, according to the slides). 2) In C, depending on compiler options, you can read from an uninitialized variable without a warning -- A new programming language might want to not auto-initialize any variables, and to throw a compile-time error if they are used before initialization. 3) In C, code like "int a = 41; a = a++" apparently compiles but leaves 'a' in an undefined state because "you can only update a variable once between sequence points" or it becomes undefined, but on many compilers works anyway. A sequence point is "a point in the program's execution sequence where all previous side effects SHALL have taken place and all subsequent side-effects SHALL NOT have taken place". -- A new programming language might want to throw a compile-time error in such a case 4) In C, the evaluation order of expressions is unspecified. so code like "a = b() + c()" can call b() and c() in any order. If they have side effects then this might matter, yet no compiler error is given. However, the evaluation order of a() && b() IS specified. -- A new programming language might want to throw a compile-time error when side-effectful code is called in context in which the order of evaluation is unspecified. Other miscellaneous gotchas: 5) In C, static vars (but not other vars) are initialized to 0 by default. -- A new programming language might want to either auto-initialize all variables, or to not auto-initialize any variables, 6) The presentation says "C has very few sequence points. This helps to maximize optimization opportunities for the compiler.". This is a tradeoff between optimization vs. principal of least surprise. -- A new programming language which wanted to make things as simple as possible would maximize 'sequence points', putting them in between practically every computation step. But some new programming languages would choose to minimize sequence points in order to allow the compiler to optimize as much as possible. 7) The presentation says that the standard says that source code must end with a newline. -- Imo that's a bit pedantic and the ideal programming language would not care if code ended in a newline. 8) In one context (inside a function), the 'static' keyword is used to make a variable persist across calls to that function. But in another context (outside of any function), the same 'static' keyword is used as an access modifier to define visibility to other compilation units! -- Using the same keyword for two different (albeit related) purposes is confusing. A new programming language might either drop one of those features entirely, or have a distinct keyword for it.