135

I am considering learning C.

But why do people use C (or C++) if it can be used 'dangerously'?

By dangerous, I mean with pointers and other similar stuff.

Like the Stack Overflow question Why is the gets function so dangerous that it should not be used?. Why do programmers not just use Java or Python or another compiled language like Visual Basic?

Tristan
  • 1,285
  • Comments are not for extended discussion; this conversation has been moved to chat. –  Jun 08 '16 at 22:37
  • 172
    Why do chefs use knives, if they can be used 'dangerously'? – oerkelens Jun 09 '16 at 08:24
  • 82
    With Great Power Comes Great Responsibility. – Pieter B Jun 09 '16 at 11:15
  • There was a related question on the Security site recently, though it was closed. – Dan Getz Jun 09 '16 at 11:55
  • 2
    Also be aware that elements of C's syntax a quite pervasive https://en.wikipedia.org/wiki/List_of_C-family_programming_languages – TJA Jun 09 '16 at 12:10
  • Same reason why would I cook my own meals if it's quicker to just buy McDonalds or a frozen dinner? Sometimes I need a meal quickly, and sometimes I can take the time for a home-cooked meal. – Ed Griebel Jun 09 '16 at 12:44
  • Scalpels are very dangerous if you're not careful. – John U Jun 09 '16 at 13:02
  • 1
    'Tis a poor knife that cuts one way. – Tony Ennis Jun 09 '16 at 13:25
  • @TJA Strange they don't list any ActionScript versions. – Panzercrisis Jun 09 '16 at 15:42
  • 1
    @PieterB came here from the sidebar specifically to write that comment. Well done chap – MDMoore313 Jun 09 '16 at 17:45
  • 10
    Joe Blow, pontificate much? – Matthew James Briggs Jun 09 '16 at 19:45
  • 1
    It will be interesting to see if, in 50 years, C becomes the new FORTRAN. – End Anti-Semitic Hate Jun 10 '16 at 06:27
  • Something else that seems to have been largely overlooked. Is this your first language or do you have several languages already under your belt. Also what is it that you are intending to do with C once you've learned it. – TJA Jun 10 '16 at 08:05
  • As to why I use C, it's when I need to be a control freak but not quite down in the weeds with actual assembler code. Note most C compilers are probably actually better at generating efficient code than people these days. – TJA Jun 10 '16 at 08:08
  • 3
    With Great Responsibility Comes Great Power – Tim Boland Jun 10 '16 at 08:31
  • 1
    I still don't know why people write 600 character comments answering the question when they could just write up an answer. Comment section isn't for answers.. – Insane Jun 10 '16 at 08:32
  • 1
    What is the fun if there is no danger? ;-) – Marco Jun 10 '16 at 09:04
  • @BigHomie, snap! – Joseph Rogers Jun 10 '16 at 09:21
  • 5
    Because "Back In The Day" when C became the Language of Choice we were expected to be able to handle stuff like that, because we had to. Interpreted or byte-coded languages were too slow because the processors of the day were so much slower. (Today I can buy a low-end desktop PC with a 2+ GHz multi-core CPU and 4 GB of memory from Dell for $279. You have NO IDEA how absolutely incredible this appears to a guy like me for whom a 4 MHz PC with 640 kilobytes of memory was bliss...). Face it - Moore's Law won. Game. *Over!* – Bob Jarvis - Слава Україні Jun 10 '16 at 14:11
  • 1
    Why do Jedi wield lightsabers if they're so dangerous? – Dan Jun 10 '16 at 14:18
  • It's an accident of history and nothing more. For the last decades, efficient languages happened to be unsafe (C, C++, etc) and safe languages happened to be inefficient (C#, Java, Python, etc). If you wanted an efficient language, you pretty much had to use an unsafe one, because there wasn't much competition. In the last few years this situation is changing, with languages that are both safe and efficient (Rust, Go, D, etc). If the new competition proves good enough, the old ones will be replaced. – Theodoros Chatzigiannakis Jun 11 '16 at 11:48
  • 6
    @Bob Jarvis: Game not over. If you think your 2+GHz, 4GB PC - or for that matter, your cluster of several hundred 4 GHz PCs with the latest CUDA GPUs, or whatever - is fast enough, you simply aren't working on hard enough problems :-) – jamesqf Jun 11 '16 at 23:03
  • 1
    Why do people drive sports cars? – Daniel R Hicks Jun 12 '16 at 12:26
  • 4
    @TheodorosChatzigiannakis Lumping C++ in with C in this context seems disengenuous to me. C++ provides lots of ways (if not necessarily the most ways) to ensure safety, but doesn't burden the user with them by default like many Other Languages do. That's why we have this catchphrase: You don't pay for what you don't use. In most cases, it can be as carefree/fast or as paranoid/slow as you want, or anywhere in between. It's just a question of how the programmer uses it. – underscore_d Jun 12 '16 at 15:49
  • @underscore_d Yes, C++ doesn't make you pay for what you don't use -- and whenever safety costs, it's off by default. But that's exactly what we mean when we say that the language is unsafe! Compare with Rust, which also doesn't make you pay for what you don't use, but safety is on by default -- because there is no cost to pay (thanks to the design that lends itself to powerful static analysis). And if you are willing to pay costs, then almost any language, regardless of its design, can be used in a safe manner -- including C. – Theodoros Chatzigiannakis Jun 12 '16 at 21:21
  • @DanielRHicks - Because We Can!!!!! :-) – Bob Jarvis - Слава Україні Jun 13 '16 at 02:52
  • 1
    And I'm sure it's written in the Constitution somewhere. – Daniel R Hicks Jun 13 '16 at 03:07
  • Read the story "With Folded Hands". Pray. Repeat. –  Aug 10 '17 at 18:07

16 Answers16

248
  1. C predates many of the other languages you're thinking of. A lot of what we now know about how to make programming "safer" comes from experience with languages like C.

  2. Many of the safer languages that have come out since C rely on a larger runtime, a more complicated feature set and/or a virtual machine to achieve their goals. As a result, C has remained something of a "lowest common denominator" among all the popular/mainstream languages.

    • C is a much easier language to implement because it's relatively small, and more likely to perform adequately in even the weakest environment, so many embedded systems that need to develop their own compilers and other tools are more likely to be able to provide a functional compiler for C.

    • Because C is so small and so simple, other programming languages tend to communicate with each other using a C-like API. This is likely the main reason why C will never truly die, even if most of us only ever interact with it through wrappers.

  3. Many of the "safer" languages that try to improve on C and C++ are not trying to be "systems languages" that give you almost total control over the memory usage and runtime behavior of your program. While it's true that more and more applications these days simply do not need that level of control, there will always be a small handful of cases where it is necessary (particularly inside the virtual machines and browsers that implement all these nice, safe languages for the rest of us).

    Today, there are a few systems programming languages (Rust, Nim, D, ...) which are safer than C or C++. They have the benefits of hindsight, and realize that most of the times, such fine control is not needed, so offer a generally safe interface with a few unsafe hooks/modes one can switch to when really necessary.

  4. Even within C, we've learned a lot of rules and guidelines that tend to drastically reduce the number of insidious bugs that show up in practice. It's generally impossible to get the standard to enforce these rules retroactively because that would break too much existing code, but it is common to use compiler warnings, linters and other static analysis tools to detect these sorts of easily preventable issues. The subset of C programs that pass these tools with flying colors is already far safer than "just C", and any competent C programmer these days will be using some of them.


Also, you'll never make an obfuscated Java contest as entertaining as the obfuscated C contest.

Robert Harvey
  • 199,517
Ixrec
  • 27,771
  • Comments are not for extended discussion; this conversation has been moved to chat. –  Jun 08 '16 at 22:39
  • 1
    "With great power, comes great responsibility" – user2762451 Jun 09 '16 at 11:23
  • 7
    "lowest common denominator" sounds disparaging. I'd say that, unlike the many far heavier languages, C doesn't enforce a tonne of extra baggage you don't need and gives you a lightning-fast base on which to implement stuff you do need. Is that what you meant? – underscore_d Jun 09 '16 at 11:57
  • 9
    "You can't really have one without the other.": actually many new languages (Rust, Nim, D, ...) attempt to. This basically boils down to matching a "safe" subset of the language with a couple "unsafe" primitives for when this level of control is absolutely necessary. However, all of those build on the knowledge accumulated from C and C++, so maybe it should be said that at the time C and C++ were developed, you could not have one without the other, and nowadays there are language that attempt to partition off their "unsafe" bits, but they have not caught up yet. – Matthieu M. Jun 09 '16 at 12:00
  • @MatthieuM. Note that a lot of this has already been discussed in the comment chain that got moved to chat. Best not to rehash all of it again. But feel free to make a suggested edit. – Ixrec Jun 09 '16 at 12:18
  • @Ixrec: Yes, I read the chat, I was just feeling that it might be useful to include it in the answer. I'll try to edit then, feel free to revert if you're not happy with it. – Matthieu M. Jun 09 '16 at 12:21
  • 6
  • is not a valid point! C took features from Algol 68, which is a "safe" language in this sense; so the authors knew about such languages. The other points are great.
  • – reinierpost Jun 09 '16 at 15:44
  • 1
    @MatthieuM. Nice edit; thank you. That sentence bothered me as well, because it was quite misleading. However, I do think it's important to note that Rust without unsafe blocks is strictly less powerful (in the sense of "what can be implemented") than Rust with unsafe blocks, so in some sense it really is true that some level of "unsafety" is necessary for certain types of "power" (though I think the word "power" is easily abused here because it's semantically overloaded). I'm guessing that, for instance, a device driver couldn't be implemented without unsafe. (I could be wrong.) – Kyle Strand Jun 09 '16 at 16:28
  • Obfuscated C contest would be a lot more boring without cpp. – Thorbjørn Ravn Andersen Jun 09 '16 at 21:59
  • @MatthieuM. Agreed on all counts! – Kyle Strand Jun 10 '16 at 06:19
  • 4
    @MatthieuM. You might want to look at Microsoft Research as well. They've produced a few managed OSes over the past decade or two, including some that are faster (completely accidentally - the primary goal of most of these research OSes is safety, not speed) than an equivalent unmanaged OS for certain real-life workloads. The speedup is mostly due to the safety constraints - static and dynamic executable checking allows optimizations that aren't available in unmanaged code. There's quite a bit to look at, all in all, and sources are included ;) – Luaan Jun 10 '16 at 13:13
  • 3
    @Luaan: Midori looks so awesome; I am always looking forward to Joe's blog articles. – Matthieu M. Jun 10 '16 at 13:28
  • @KyleStrand: Device drivers generally require access to the underlying hardware, which can be difficult to do in a managed language. Also, I can imagine some very tight loops. – Robert Harvey Jun 10 '16 at 15:59
  • @RobertHarvey Did you mean to address that comment to Luaan? I don't think I brought up managed languages....? (Rust is not managed, if that's what you're thinking....) – Kyle Strand Jun 10 '16 at 16:52
  • @KyleStrand: Ah, that's very interesting, I didn't know that. Generally, I associate "unsafe" code with C, and "not unsafe" code as managed. – Robert Harvey Jun 10 '16 at 16:58
  • 3
    @RobertHarvey Which is exactly why Rust is so promising! Please do yourself the favor of looking into it. I think your safe/managed dichotomy view is pretty common in the C/C++ community--for instance, I was once explaining a problem in C++ that, I claimed, wouldn't arise in Rust, and someone responded, "how does Rust deal with this situation? My theory - garbage-collected pointers. :-)". I believe an early version of Rust did have a GC, but as of version 1.0 it was long gone. – Kyle Strand Jun 10 '16 at 22:04
  • 1
    @RobertHarvey Another intriguing response from that thread -- "It really saddens me to see people blaming C++ while the compiler is doing its best (and will do better with concepts) to scream their logical mistake at them." This was from someone who claimed my C++ problem was really a "logic problem" because they simply didn't understand the solution I was trying to describe which works perfectly fine in Rust (but can't be implemented with the C++14 standard library). – Kyle Strand Jun 10 '16 at 22:06
  • Also, this comment thread has gotten a bit out of hand... if only we had some way to migrate to chat. – Kyle Strand Jun 10 '16 at 22:21
  • 2
    If only this comment thread wasn't a complete rehash of the previous comment thread that was migrated to chat days ago... – Ixrec Jun 10 '16 at 22:29
  • 3

    A lot of what we now know about how to make programming "safer" comes from experience with languages like C. Completely false. We had safe(er) compiled systems languages before C. Programmers saw C and preferred it to the boring, bondage-and-discipline cruft that made them go through verbose hoops to just get to a word in memory and do what they want (if even possible at all).

    – Kaz Jun 11 '16 at 15:03
  • is a much easier language to implement because it's relatively small, Have you seen the ISO C standard lately?

    – Kaz Jun 11 '16 at 15:04
  • 2
    At the time C exploded in popularity, it was a quite small language, and that, more than opinions about bondage-and-discipline languages, contributed to its growth. A huge number of new platforms got C because you generally need only a small amount of system-specific code to bring a C compiler up. – Russell Borogove Jun 12 '16 at 03:03
  • "Good judgment comes from experience. Experience comes from bad judgement." And, the resulting judgment often makes us needlessly cautious and overprotective of others just learning. Of course, they might end up writing code for our self-driving cars, so maybe it is good to be overcautious... Most accidents happen at home, in the bathroom, with kitchen in second place. Can't make everything safe apparently. Inflatable toilets and bathtubs have not caught on. –  Aug 10 '17 at 18:12
  • While it's a common conflation, "systems language" wasn't intended to be a synonym for "low-level language" or "bare-metal language" but, rather, a label for languages that are designed to manage and mitigate complexity over the full lifecycle of a large, long-lived project (typically used as infrastructure that others build on) with shifting maintainership. See What is Systems Programming, Really? by Will Crichton for a well-cited run-down of that. By that definition, Java and Go are both systems languages, just not bare-metal ones. – ssokolow Sep 30 '21 at 23:25