10 ms·
Can't this reasoning be applied recursively? If you're going to learn C, you better learn assembly, so you know what the C is doing. If you're going to learn
by prophetjohn 14y ago
Can't this reasoning be applied recursively?
If you're going to learn C, you better learn assembly, so you know what the C is doing.
If you're going to learn assembly, you better learn CPU architecture, so you know what the assembly is doing.
If you're going to learn CPU architecture, you better learn digital logic, so you know what the adders and multiplexers are doing.
If you're going to learn digital logic, you better learn solid-state physics...
I mean, it's always useful to know what's happening under the hood, but it's not always realistic to expect that to happen. I don't think the average C programmer need to know assembly any more than the average Ruby programmer needs to know C.
- ori_b 14y agoI've played around with all of those levels at various points in school and my career. My knowledge of solid state physics mostly goes unused, mostly, but every other level is something I've had in mind at various points. I'd file them all under "good to know". Sure, you can generally get by without low level knowledge, but it's nice knowing why certain design decisions were made. And as far as C goes, I think it's extremely useful to be familiar with how it translates to assembly, at least in general. It is knowledge that you will use regularly if you're programming in C in any significant capacity. For example, reasoning about ABIs is something you'll have to do if you ever write a stable library interface. Reasoning about ABIs requires you to know the asm-level calling convention for the platform you're coding on.
- prophetjohn 14y agoThe implication was that you need to know assembly if you're going to be a C programmer. If you can "get by fine without," that's close to the definition of not specifically needing it. Knowing the next layer down is definitely useful, though.
- flatline3 14y agoHe stated that 'you can get by', not that 'you can get by fine'. Writing C without knowing basic assembly is writing code you can't debug. I'd say that's clearly not acceptable.
- prophetjohn 14y agoWhat's an example of a bug in C that cannot be diagnosed without knowledge of assembly?
- flatline3 14y agoCan I include compiler bugs? I've had to deal with a slew of those over the years. If we put those aside, then the simplest example is probably when someone else's code crashes due to your input (though the bug may be theirs), and you don't have their source code. I've spent a great deal of quality time tracking down bugs in vendor libraries for which I had no source, and then working around them. There are a ton of other possibilities, though. For instance, ordering issues related to thread-safety, out-of-order execution, and synchronization points/barriers. Or, hell, just being able to read a failure quickly, whether or not you have debug symbols handy. Contrived example: Program received signal EXC_BAD_ACCESS, Could not access memory. Reason: KERN_INVALID_ADDRESS at address: 0x0000000000000000 0x0000000100000f25 in main () (gdb) disassemble Dump of assembler code for function main: ... 0x0000000100000f25 <main+21>: movb $0xff,(%rax) ... End of assembler dump. (gdb) info reg rax rax 0x0 0
- prophetjohn 14y agoI think this is a valid example of reasons where it would be helpful to know assembly as a C programmer, but not justification for the claim that writing C without knowing assembly is writing code you can't debug. Even if you are having problems interfacing with a third party library, most of this stuff is pretty Googleable. I think a good summary of my opinion would be that if you're going to primarily write C professionally throughout your career, it's best to understand fundamentals of assembly, but doing projects here and there? I don't think it's worth the time; you just won't use it that much.
- flatline3 14y agoC isn't the kind of thing you dabble in.
- tmurray 14y agoI don't think that is true. If you're writing C, it's probably because you want to be close to the metal and want many of the guarantees that such proximity provides. If you're focused on that sort of thing, then it's definitely useful to understand what your compiler is actually outputting so you can react accordingly. (I'm a C programmer, I don't look at assembly that often at all, but it's certainly helpful to be able to do so and my knowledge of the x86 ISA, calling conventions, etc has informed many decisions I've made in the past, especially re: performance)
- prophetjohn 14y agoIf you want to know what GCC is outputting, you need to learn a hell of a lot more than just x86 assembly. You're going to have to do quite a bit of study of compiler theory. Run objdump on some non-trivial C program and the direct flow of logic will not likely directly resemble the C you wrote.
- flatline3 14y agoYou don't need to study compiler theory to understand the kind of code the compiler will output. That's very easy to reason about, and much harder to implement. Knowing x86 assembly is more than enough to reason backwards from assembly to the C that generated it.
- wreckimnaked 14y agoI mean, it's always useful to know what's happening under the hood, but it's not always realistic to expect that to happen. I don't think the average C programmer need to know assembly any more than the average Ruby programmer needs to know C. I disagree. Given that C exposes you to some hardware details that are abstracted when developing in some higher level language such as Ruby, for instance having to deal with overflow on signed/unsigned types and register variables (I know that compilers will mostly ignore that, but it's still a language feature). The average Ruby programmer, on it's turn, can perfectly live without knowing C programming. A more accurate analogy would be to a Ruby programmer to know about the language implementation being using (MRI, JRuby, Rubinius, etc.)
- prophetjohn 14y agoSigned vs. unsigned data types isn't an artifact of assembly language. It's more so one of digital data representation. I think that knowledge is just as useful to a C programmer as a Ruby programmer. Fire up irb and type 0.1 + 0.2, for instance. You covered what I would have said about the register keyword, but you're right, it's essentially impossible to understand that language "feature" without having a basic understanding of the CPU.
- wreckimnaked 14y agoIndeed. My main point was that programming C requires more knowledge about the "layers" underneath its execution than higher level languages such as Ruby.
- Homunculiheaded 14y agoI think someone who claims expertise in 'software' should understand the process until it stops being software, which is architecture. Honestly I think the 'average' Ruby programmer ('average' reflecting their understanding of ruby) who really claims to understand software should know C and ASM. I really don't have an issue with someone being a dev in Ruby who doesn't understand pointers or how if/else statements can be constructed from jmp primatives. But if you're on the road to expertise I don't think you can remain ignorant of these.
- xradionut 14y ago"I think someone who claims expertise in 'software' should understand the process until it stops being software, which is architecture." Having a broad background is useful even if it's considered "architecture". Knowledge of networks and protocols is essential. Having IT chops is a great toolkit to draw from. A DBA will need to know more about storage than most developers. Understanding some RF basics helps when dealing with wireless. I've probably used more of my EE background dealing with lower levels of the stack than my CS background.
- tsahyt 14y agoI think a good C programmer should have a grasp on how assembly works. This can come in incredibly handy for debugging weird errors. Yes there are bugs that are weird enough to only become evident in assembly code. An understanding of assembly also makes memory management and pointers in C so much more understandable. Also, assembly reveals quite a bit about performance: Less instructions == faster code. Then there are some platform-specific things that aren't available[1] from C (at least the standard library) like SSE or MMX instructions. These can give you a big speedup (think of it as "micro-parallelization") if used correctly. Some things in glibc (mainly in string.h) are implemented using them, but as far as I know the standard library doesn't provide an interface to them and the compiler usually isn't smart enough to use them when appropriate. So if you're trying to squeeze the last bit of performance out of a program you'll often have no choice but implementing a bit of assembly code as well. Concerning architecture: One might argue it's not neccessary but I think a good C programmer should at least have scratched the surface here. No deep understanding, but a bit of an overview of what's going on. That is - I think - the point where it no longer concerns you as a programmer. Architecture and Assembly really go hand in hand, since every architecture comes with its own assembly code (yes I know, some assemblers are abstracting that away sometimes). That is why some things work faster on, say SPARC than on x86. It also helps understand the limits we're given and what "64 bit" really means. Understanding architecture doesn't really help writing better C code, but it explains things the compiler does, since in a pipelined architecture, the compiler will arrange assembly instructions, so there are as little stalls as possible and therefore gaining performance. [1] I might be wrong on that though. Please correct me if I am.
- whatshisface 14y agoIt can be applied recursively, but with diminishing returns and an increasingly alien (to a software developer) set of rules as you go down. If learning one thing made you 10% better at the thing above it, you would also become 1% better at the thing above that.
- agumonkey 14y agoThere's a course adressing this, full stack knowledge but from bottom to top. Building a system from 'Nand to Tetris' as they pitch it. They probably left ceramics as an exercise for the reader. http://www1.idc.ac.il/tecs/ http://www1.idc.ac.il/tecs/
- iyulaev 14y agoI think you should know at least one level of abstraction, in each direction, beyond what you presently know. So if you're writing a C driver, you should know what the assembly will look like and also what the application developer will be writing with the help of your driver. This probably has more to do with communication and understanding of the people problems involved than with performance though.
- ChuckMcM 14y agoIt worked for me.
- anonymous 14y agoYou forgot one: If you're going to learn Python, you better learn C, so you know what the Python libraries are doing. Dig deep enough into any language, and most times you'll find some things written in C. Thus learning some assembly and some C will touch a lot of other languages. It will touch a lot of programming. The operating system you use is probably written in C. Is it a complete waste of time to know assembly and C? That seems like a no brainer. (So even if you have a huge brain that has little trouble thinking in scripting language code but can't seem to register any common sense, you should still be good to go.) The truth is, it doesn't matter what you think. The world has already decided the question. All Computer Science students are required to take a class that teaches assembly, despite the fact they may never be writing programs using it after they graduate. Maybe there's a reason for this. You can see a similar pattern in other subjects: having to learn one thing before you proceed to learn another. Universities call them "prerequisites". But anyone who has been a student knows that often you could skip the prerequisites and still pass the courses that you need them for. So are prerequisites just hoop jumping for the sake of hoop jumping? Or is there actually a reason behind this? Is it some sort of "foundation building"? You can skip over whatever you want to; programming is not a licensed profession and you do not need a Computer Science degree to program. But I doubt you'd want to find out your surgeon skipped learning basic science and jumped right into some particular branch of surgery. But hey, programming is not surgery. And if some hooligan gets your daughter pregnant, I doubt you'd let him off the hook because he had only learned how to have sex and couldn't be expected to also understand what was happening "under the hood".
- eswangren 14y agoReductio ad absurdum is a logical fallacy.
- ericd 14y agoWelcome to the MIT EECS degree program, quite literally :-D
- bigiain 14y agoIt certainly works back up the other way, lots of bits of Perl make a lot more sense with some C background. And, FWIW, when I did CompSci back in the '80s, the first courses/tutorials involved building half-adders and flip-flops from NAND gates and wires on a plug-board. You don't _need_ to know that sort of stuff, especially not in any level of detail, to build another CRUD webapp - and with luck a hugely successful business on the back of your CRUD app - but I think there's a personality trait that comes along with all the other stuff that makes some people "hackers" which characterises many of us as insanely curious. Many of us don't want to treat the latest Ruby ORM features or Node.js's async callbacks as a "black box", we want to "know how it works" - sometimes out of pure curiosity, and sometimes because it fails _hard_ and we can't work out why without understanding what it's doing "under the hood".
- irishcoffee 14y agoMy comp. sci. program stopped at the solid-state physics point in your recursion example. Every step has made me a better programmer.
- prophetjohn 14y agoSame here. But how much digital logic made me a better programmer is on the order of how much my calculus classes made me a better programmer. I think that my knowledge of architecture has influenced my C skills more than my assembly knowledge.
- tsahyt 14y agoMy calculus classes actually have made me a better programmer. Depends on the problems you're facing though.
- irishcoffee 14y agoI would argue that knowledge of Assembly and knowledge of Architecture go hand-in-hand. I can't imagine many people who actually 'get' Assembly saying 'I don't understand Architecture' Also, I went through some low-to-mid range math in school (calc-3, diff. eq., linear alg.) and those classes very much made me a better programmer. The analytic thought processes you learn through those classes is invaluable.
- jonhess 14y agoThere are diminishing returns to going deeper and deeper. But there's a big return for the first level. I think it's useful to have a basic understanding of assembly so that you can debug better, or understand why some behaviors are undefined. I think that only takes a basic understanding of assembly though. If you want to be an expert at assembly, you probably want to go deeper, but most people don't have that goal.
- thirdhaf 14y agoIn a strange way I sort of did this with my EE and math degrees. I did draw the line at the Hartree-Fock approximation for doing ab-initio band structure calculations for silicon though so there's still room at the bottom for me. Since then I've come to realize that programming is more fulfilling to me but I do feel prepared for this particular line of rabbit-hole questions :-)
- qznc 14y agoWith a diminishing amount of knowledge you might be right. A master C programmer knows assembly well, a good chunk about CPU architecture, some things about digital logic and superficially about the physics.
- Toenex 14y agoThe best undergraduate project I ever did was one where we had to design and simulate a 4 bit microprocessor (this was 1991). Whilst it pulled together strands of our analogue and digital electronics classes the biggest impact was on my software development. It brought the programmers model of a CPU completely to life and stuff that I knew I now Knew. I became a pretty mean C programmer (even if say so myself) because of this. How far you go down the rabbit hole depends of how much of this supporting knowledge you need to work at the level you work. Given the layers of software abstraction that exist in systems these days is it really necessary for a programmer to have a detailed knowledge of how a transistor works? Not at all. Your much better spending the time building a mental model of how your VM or OS layer is working and going to interpret the code you write. Or even looking up and understanding the layers that will use what you write - like users and customers (now there is a real challenge!) For sure take an interest in all things, but as you go down the layers your thinking can be increasingly abstract and like any model, plain wrong and it won't really matter.
- perlpimp 14y agoDomain of working with C implies working with hardware and raw code - instructions that CPU executes. Same as working with JavaScript(in browser) suggests knowledge of how browsers parse HTML, generate DOM tree and subsequently render it. When things go wrong it is useful to have knowledge of n-steps deep to immediately cut through ton of output and nail down a few places things seem to work not as expected.
- tapertaper 14y agoIf you wish to make an apple pie from scratch, you must first invent the universe. -Carl Sagan