Slashdot Mirror


What's To Love About C?

First time accepted submitter edA-qa writes "Antiquated, clunky, and unsafe. Though beloved to some, C is a language that many choose to hate. The mass opinion is indeed so negative it's hard to believe that anybody would program anything in C. Yet they do. In fact a lot of things, even new things, are programmed in C. The standard was recently updated and the tools continue to evolve. While many are quick to dismiss the language it is in no danger of disappearing."

793 comments

  1. because by Anonymous Coward · · Score: 4, Funny

    char *post = "first";

    1. Re:because by Anonymous Coward · · Score: 5, Insightful

      Using a string literal as not const is very bad form.

    2. Re:because by Anonymous Coward · · Score: 0

      char *post = "first";

      const char* post = "first";

    3. Re:because by Anonymous Coward · · Score: 4, Funny

      Back to C++ Land with you, rascal!

    4. Re:because by localman57 · · Score: 5, Informative

      No, he's right. On systems where your constants exist in a different medium than your variables (such as microcontrollers where variables are in RAM but constants are in flash), declaring a string as const or not const can have a big impact on what resources you eat up. Typcially, there's often a #pragma or non-standard keyword such as ROM that goes along with this.

    5. Re:because by Anonymous Coward · · Score: 0

      #constlol char *parent_post = "fail"

    6. Re:Because by jellomizer · · Score: 1

      Just because you are programming in a Lower Level language... It doesn't mean all your code will be faster.

      When you code in C (or any other language) your goal is usually focused on your final project. Even with a degree in computer science, you may not have focused all your code to be optimal, (you are short on time so you put a bubble sort in it). Compared with Java where you do a .Sort() to your string class... Chances are it will be coded with a Faster sorting algorithm. Because the person who programmed Java .Sort() class, their business requirement wasn't to make a large project, but an efficient sort algorithm.

       

      --
      If something is so important that you feel the need to post it on the internet... It probably isn't that important.
    7. Re:because by Anonymous Coward · · Score: 1

      const char* post = "first"

      you troglodyte.

    8. Re:because by Anonymous Coward · · Score: 1

      Bullshit. Literal strings exist in the RO section and can trivially be placed into ROM. A literal string is always const char *. Here he is assigning a const char * to a char *. The latter type does nothing to affect the literal string placement in standard C.

      Assigning a literal string to a char * is bad form because of the above - if it is in ROM, you're fucked when you write to it, and you're exploiting undefined behaviour even if it isn't in ROM.

      All this is complicated somewhat by uCs that have different address spaces for constants and for variables; it is in those cases that you *must* declare which space the pointer points into. The compiler will probably warn/error over ROM char * post = "first" but it might equally accept it and barf when you write through the ROM pointer; especially since parts of the standard C library interfaces are broken wrt const correctness anyway.

      The problem you're highlighting would occur on such a system when NONROM char * post = "first" is discovered, as it may introduce startup code to copy the string from ROM into RAM. But so would NONROM const char * post = "first". Because "const" in C doesn't guarantee anything at all about how you will later cast and use the pointer.

      So it is ROM/NONROM, not const, that changes the compiler's behaviour. const changes nothing in C because it means nothing in C.

    9. Re:because by Anonymous Coward · · Score: 0

      You sound like my professor, who didn't like my treating a string pointer as a boolean.

    10. Re:because by Anonymous Coward · · Score: 0

      Why? Because NULL might one day be nonzero?

    11. Re:because by Anonymous Coward · · Score: 0

      great way to check for null

    12. Re:because by ComaVN · · Score: 0

      I recall that the NULL pointer is not numerically 0 on some systems.

      No idea which systems those were tho.

      --
      Be wary of any facts that confirm your opinion.
    13. Re:because by localman57 · · Score: 3, Interesting

      In many cases, you're correct. In others, not so. It varies by compiler. This is one of the problems with the C language; it isn't equipped to deal well with multiple address spaces that overlap. If you're a compiler maker, and you need the ability to point to two different address spaces with the same numerical range, you're screwed. Either you infer meaning that isn't there in the standard (e.g. const means Flash, non-const means ram), you define non-standard keywords such as ROM, or you do run-time translation of addresses (I've only seen one compiler that tried to do this, and it was a disaster...).

    14. Re:because by Anonymous Coward · · Score: 0

      Um, I think you are both wrong.

      What you've got there is a pointer and a string. The pointer is initialised to point at the string, but none-the less you could later reassign it e.g. *post = "ac"; or *post = NULL;

      It's likely the string is still going in ROM, but you've also cost a pointer. The more correct declaration would be something like const char post[] = "first"; which also saves the need for relocation (if your platform has it).

      Obviously too many quiche eaters around here these days.

    15. Re:because by Anonymous Coward · · Score: 1

      Wouldn't matter if it were. The standard guarantees that a pointer in a Boolean expression will be false if NULL, and true otherwise.

    16. Re:because by Anonymous Coward · · Score: 0

      *post = "ac";

      I don't think that's quite right and might crash. I think you mean something like:


      char buf[8];
      post = buf;

    17. Re:because by Darinbob · · Score: 4, Insightful

      Quite a lot of languages have problems with this. I would say that 100% of the current popular languages can't do this in the standard. So it's not necessarily a valid criticism of C as a standardized language or as an abstract machine-independent language. Individual compilers though typically have a set of pragmas or attributes to handle machine specific details.

    18. Re:Because by Anonymous Coward · · Score: 0

      Um, yeah, and in C I would use bsort().

    19. Re:Because by Anonymous Coward · · Score: 0

      When people say C is faster they mean that code based on similar algorithms executes faster when done in C than in other languages. This is often true.

      Also, C has qsort. People don't write bubble sort because they are short on time. People short on time use qsort, and it is an efficient sort algorithm.

    20. Re:because by Anonymous Coward · · Score: 1

      The bit pattern might not be zero on some system you'll never see and your code will never be ported to, but it doesn't matter because the language covers over that implementation detail and makes the null pointer look like a zero anywhere that it matters.

    21. Re:because by javaxjb · · Score: 1

      AS/400 (or iSeries or whatever IBM's name of the year is) can have null pointers that are a negative offset (but so far as I ever saw, only for programs running in batch and never interactively). So, if you try some trick comparing current pointer location as beyond a prior pointer location to track a locations in a data area to save an explicit check for 0 it will work every time interactively and randomly cause a null pointer exception in batch (something I had never noticed in K&R until someone pointed it out to me). I might have the details slightly wrong. That was over a decade ago and I've only written a few simple C utilities since then.

      --
      Programmers in mirror are brighter than they appear
    22. Re:because by RoccamOccam · · Score: 1

      I believe that was an issue for the Inmos Transputer. The Transputer used a signed address space, so memory location 0 was in the middle of the address space.

    23. Re:because by Anonymous Coward · · Score: 0

      The first is dynamically allocated, yours is statically allocated.
      In the case of a string, where you likely don't know how long it will be, it's better to allocate dynamically.

      But what's more important, don't forget to clean it up afterwards.

    24. Re:because by Megane · · Score: 2

      Bullshit. Literal strings exist in the RO section and can trivially be placed into ROM. A literal string is always const char *. Here he is assigning a const char * to a char *. The latter type does nothing to affect the literal string placement in standard C.

      Then don't ever try to program a Harvard address space architecture like AVR. Unless you specify otherwise, all string literals get copied at start-up from the ROM address space into the RAM address space so they can use compatible pointers. That doesn't work very well when you only have a couple kilobytes of RAM, and want to use a lot of read-only data. To work around this, you have to use a few non-standard extensions to have pointers that reference ROM address space, and pass them to routines that know they refer to ROM data.

      And even without that, compilers for embedded programming know that an initialized "static const" global goes in the read-only (.text) segment, not the read-write (.data) segment.

      --
      #naabhaprzrag, #sverubfr-000, #agi-fcbafberq, negvpyr[pynff*=' negvpyr-ary-'] { qvfcynl: abar !vzcbegnag; }
    25. Re:because by loufoque · · Score: 1

      To those that didn't understand the above comment, bear in mind that a string literal is of type char[N] in C, but const char[N] in C++.

    26. Re:because by Dachannien · · Score: 4, Funny

      No, he's right. On systems where your constants exist in a different medium than your variables (such as microcontrollers where variables are in RAM but constants are in flash), declaring a string as const or not const can have a big impact on what resources you eat up. Typcially, there's often a #pragma or non-standard keyword such as ROM that goes along with this.

      And this is particularly relevant in this case, because Slashdot runs on CowboyNeal's microwave oven.

    27. Re:because by Anonymous Coward · · Score: 1

      not precisely. at a language level, the null pointer constant is and always has been "An integer constant expression with the value 0, or such an expression cast to type void *, is called a null pointer constant" (that's from the standard).

      Likewise, NULL is always defined as a valid "null pointer constant".

      The confusion stems from the fact the machine level representation of NULL may or may not be numerically 0, but, this is never your concern. The programmer always uses the "null pointer constant" (as defined above) and it is up to the *compiler* to convert this to the machine specific null value for you when used in a pointer context.

      This has some subtle side effects though. For example:

      int *p;
      memset(&p, 0, sizeof(p)); /* incorrect, because this is assigning the litteral bit pattern of 0 to the pointer, which may not be correct for this arch */
      p = 0; /* correct, the compiler will assign the correct null value bit pattern here */
      p = NULL; /* also correct */
      p = 0UL; /*also correct */
      p = (void*)0; /* still correct :-P */

    28. Re:because by mooingyak · · Score: 1

      The first is dynamically allocated, yours is statically allocated.
      In the case of a string, where you likely don't know how long it will be, it's better to allocate dynamically.

      But what's more important, don't forget to clean it up afterwards.

      char *post = "ac";

      is not dynamically allocated, and trying to free it later is not a good idea.

      Incidentally, this thread is one of the reasons I hate C.

      --
      William of Ockham had no beard. The most likely explanation is that it was chewed off by squirrels every morning.
    29. Re:because by mooingyak · · Score: 4, Insightful

      And this is particularly relevant in this case, because Slashdot runs on CowboyNeal's microwave oven.

      Ovens. You really think it's not a cluster?

      --
      William of Ockham had no beard. The most likely explanation is that it was chewed off by squirrels every morning.
    30. Re:Because by Anonymous Coward · · Score: 0

      Just because you are programming in a Lower Level language... It doesn't mean all your code will be faster.

      Agreed, it's the algorithms that generally make code fast or not, not the language.

      When you code in C (or any other language) your goal is usually focused on your final project. Even with a degree in computer science, you may not have focused all your code to be optimal, (you are short on time so you put a bubble sort in it). Compared with Java where you do a .Sort() to your string class... Chances are it will be coded with a Faster sorting algorithm. Because the person who programmed Java .Sort() class, their business requirement wasn't to make a large project, but an efficient sort algorithm.

      This point is meaningless. libraries solve this "issue" in every way. In C, well you can just use qsort from the standard library. Which you can rest assured is done well. You don't have to write it yourself.

      Even better, c++ has a rather large algorithms library which provides very efficient implementations of the most common algorithmic needs. For example, sorting... The difference in c++ is that because of templates, I can sort *anything*, not just strings. I can even provide a predicate to sort by something other than natural order if i wish. It's simply more flexible.

    31. Re:because by Anonymous Coward · · Score: 0

      Bullshit yourself. In C (this is not about C++), a string literal has type array of char, which decays to char *, not const char *. You're not allowed to modify the string literal, but it doesn't have const in its type.

    32. Re:because by Old+Wolf · · Score: 1

      No, he's right. On systems where your constants exist in a different medium than your variables (such as microcontrollers where variables are in RAM but constants are in flash), declaring a string as const or not const can have a big impact on what resources you eat up.

      He's right , but your reason is not :)

      Whether "first" is stored in the const data area or not depends on your compiler/linker settings. You can legally write char *post = "first"; in either case, just your program goes balls up if it does get stored in const data and you later try to write that data through 'post'. The 'good form' version of the code, i.e. char const *post, goes a long way toward preventing you from trying to write the const data area.

    33. Re:because by Old+Wolf · · Score: 1

      Incidentally, this thread is one of the reasons I hate C.

      Yeah. The threads fill up with the same old misconceptions that are fixed on page 1 if the posters actually read a book on C (excluding books by H Schildt I guess).
      In before "NULL != 0 sometimes" or "arrays are implemented as pointers"

    34. Re:because by jc42 · · Score: 1

      char *post = "first";

      Using a string literal as not const is very bad form.

      Don't know much about C, do we? ;-)

      If I saw the above declaration, I wouldn't be at all surprised to see a later command like:

      post = "second"; // Or perhaps some computed value

      If the declaration had contained a const, this would be a syntax error, since the variable post has been declared a constant.

      Any competent C programmer would use the const only when it's appropriate, to tell the compiler that a symbol isn't a variable.

      I've seen any number of cases of managers imposing bogus "rules" like this, causing any number of problems for the programmers. One of my favorites, because of its sheer silly cluelessness, is the managers who insisted that if commands must always have an else clause. Really. I've seen this on a number of projects. Of course, you can always put a do-nothing command there, if your language doesn't allow empty else clauses, but it doesn't endear you to later readers who have to try to figure out why there are utterly pointless commands scattered around in the code, making it bigger for no good reason other than to interfere with readability.

      --
      Those who do study history are doomed to stand helplessly by while everyone else repeats it.
    35. Re:because by Old+Wolf · · Score: 1

      In many cases, you're correct. In others, not so. It varies by compiler. This is one of the problems with the C language; it isn't equipped to deal well with multiple address spaces that overlap. ...you define non-standard keywords such as ROM, or you do run-time translation of addresses...

      Having used various embedded compilers, I don't agree with this. The C standard is carefully designed to support this situation, a pointer of "void *" must be able to point to any of the address spaces. This means it's got to have more bits in it than the size of the address space of course, but this is fine and works well. (example - overlapping 16bit address spaces, the void* pointer needs to be 3 octets at least).

      In this example, the compiler can offer non-standard keywords as well, so the programmer can use pointers of 2 octets at his own risk if that optimization in storage space is needed; and the compiler should flag an error (compile time if possible; otherwise runtime) if pointers to different address spaces are mixed.

      There's only trouble with sloppy coders who don't adhere to standards, but what can you do about that?

    36. Re:Because by Anonymous Coward · · Score: 0

      And there are plenty of sorting C libraries out there. In fact, you can probably find a sort that is optimized for your specific case, instead of using a generic sort.

    37. Re:because by CubicleZombie · · Score: 1

      I've gone through a few "C for Dummies" style books, but I'd like a better understanding. Is there a C book that you would recommend?

      --
      :wq
    38. Re:because by Iniamyen · · Score: 1

      On the contrary, the default else clause is there so the next poor sap who has to pick up your code can actually trace each construct without pulling their hair out. If you need to make it obvious, you can always put a comment in the empty else clause that explains why there is an empty else clause :)

      /* Comments are always good... */

    39. Re:Because by Anonymous Coward · · Score: 0

      #include
      void qsort( void *buf, size_t num, size_t size, int (*compare)(const void *, const void *) );

      Wow, that was time consuming...

    40. Re:because by gnasher719 · · Score: 2

      I recall that the NULL pointer is not numerically 0 on some systems.

      NULL is not a pointer. NULL is a macro which evaluates to a null pointer constant. And a null pointer constant is either an integer constant expression with a value of 0, or such an expression cast to void*.

      What you are thinking about is probably a null pointer. Completely different thing. But a null pointer is a pointer, and pointers are not anything numerically. They are pointers. Pointers and numbers are different things.

      Now just as converting from int to float will (almost always) change the bits in a value that is converted, so can converting from int to a pointer type and back. It often doesn't, but it can.

    41. Re:Because by FormOfActionBanana · · Score: 1

      Yeah, or even more "efficiently" than you ever would have dreamt...
      http://cwe.mitre.org/data/definitions/14.html

      What was your password again?

      --
      Take off every 'sig' !!
    42. Re:because by drewm1980 · · Score: 1

      The cluster that runs Slashdot ~is CoyboyNeal's oven!

    43. Re:because by rrohbeck · · Score: 1

      Variables won't;
      Constants aren't.

    44. Re:because by tzanger · · Score: 1

      Illustrating C by Donald Alcock is pretty good.

    45. Re:because by acid_andy · · Score: 1

      *post = "ac"; is not reassigning the pointer. The * is dereferencing the pointer so you're actually attempting to write a value to the memory location addressed in post. The memory address in post wouldn't change. Also you'd likely get errors if your C compiler does type checking as you're trying to assign an array of chars to a single char location. *post = 'a'; would be valid and *(post+1) = 'c';. Of course, if it was initialised in ROM this will fail miserably.

      If you were actually wanting to reassign the pointer's address so it points to your different string it would be const char * other = "hello"; post = other;

      I love C.

      --
      Your ad here.
    46. Re:because by dmbasso · · Score: 4, Informative

      Don't know much about C, do we? ;-)

      He does, you not so much.

      If I saw the above declaration, I wouldn't be at all surprised to see a later command like:

      post = "second"; // Or perhaps some computed value

      If the declaration had contained a const, this would be a syntax error, since the variable post has been declared a constant.

      Nopz, what was declared as constant is the memory the pointer is pointing to. Example:

      1: void f() {
      2: const char *a="bla";
      3: a = "blu";
      4: a[0] = 0;
      5: }
      >gcc -c t.c
      t.c: In function ‘f’:
      t.c:4:2: error: assignment of read-only location ‘*a’

      Tip: avoid using snarky comments. When you're wrong it makes you look specially stupid.

      --
      `echo $[0x853204FA81]|tr 0-9 ionbsdeaml`@gmail.com
    47. Re:because by TheRaven64 · · Score: 2
      Your post is so full of errors it hurts to read. The const qualifier refers to the data, not the variable in this context. The following is entirely valid:

      const char *post = "first";
      post = "second";

      The following will have the behaviour that you are claiming:

      char *const post = "first";
      post = "second";

      This will get a compiler error, however consider this version instead:

      char *const post = "first";
      post[0] = 0;

      This will not give a compiler error, but will abort at run time. The type of a string literal is const char * and so it is placed in the constant data section, which may be in ROM on embedded systems and will be mapped read-only (and shared between processes) on other systems. The same problem will happen if you omit the const. The correct way to write this is:

      const char *post = "first";
      post[0] = 0;

      This will give a compiler error on the assignment, because you are attempting to modify constant data. You will also get a compiler warning if you try to implicitly cast to char*, because the code that receives the char* may attempt to modify the data.

      Any competent C programmer would use the const only when it's appropriate, to tell the compiler that a symbol isn't a variable

      I guess we know exactly where you fit on the C-competence spectrum then...

      --
      I am TheRaven on Soylent News
    48. Re:because by fredrik70 · · Score: 1

      bah, const is for wimps!

      --
      if (!signature) { throw std::runtime_error("No sig!"); }
    49. Re:because by Anonymous Coward · · Score: 0

      Well pragma is specifically made to contain compiler-specific commands. So you are not screwed at all. C is used so much in embedded devices, these kind of things are not overlooked. You can easily define all kinds of complicated memory schemes with the help of pragmas and a nice linker cmd-file.

    50. Re:Because by ImprovOmega · · Score: 1

      Just because you are programming in a Lower Level language... It doesn't mean all your code will be faster.

      Yes, but it has the potential to be faster - the tightest optimized C code will always outperform the tightest optimized Java code, for example.

      When you code in C (or any other language) your goal is usually focused on your final project. Even with a degree in computer science, you may not have focused all your code to be optimal, (you are short on time so you put a bubble sort in it). Compared with Java where you do a .Sort() to your string class... Chances are it will be coded with a Faster sorting algorithm. Because the person who programmed Java .Sort() class, their business requirement wasn't to make a large project, but an efficient sort algorithm.

      I'll agree with you to a point, but sometimes bubblesort is appropriate - if you're sorting a very small list (like under 100 items, guaranteed) it may not be worth the overhead of a nlgn sorter. But if you're sorting any sizable list of items the performance hit will assure you of a failing grade (in school) or a bad performance review (in the business world). Failure to understand why and how an underlying algorithm works is a recipe for disaster - see previous comments on Java Hashmap for example. It really pays to understand what's going on under the hood in your programs, otherwise you're a ticking time bomb.

    51. Re:because by Anonymous Coward · · Score: 0

      In many cases, you're correct. In others, not so. It varies by compiler. This is one of the problems with the C language; it isn't equipped to deal well with multiple address spaces that overlap.

      Not all microcontrollers have overlapping memory ranges for RAM/FLASH/EEPROM.
      Those with a 32bit address range often put them in separate areas.
      Not that this changes much. You still have to know wtf you are doing when you are coding microcontrollers.

    52. Re:because by Anonymous Coward · · Score: 0

      This is the issue with C language and the stolen book of C language. Without C language we would have to program in Assembly/Assembler = very close to punch cards. A lot of programming languages is being compile to near C compiler for speed and the rest is binary byte code. When will we have a compiler developer from those universities create a near C compiler for Python 3?

    53. Re:because by Anonymous Coward · · Score: 0

      So, this means that all of the ovens should be the same brand/model?

    54. Re:because by Douglas+Goodall · · Score: 1

      On some systems, the first few bytes in the writable data segment are reserved so that if by some quirk of fate something is written to a null pointer, it will go there and not corrupt anything. Pointer management is one of the benefits and liabilities of C. It is true that with a language that allows pointer manipulation like C, it is very hard to prove program correctness. In contrast C++ (when compiling at the highest warning level, with warning are errors) code generally does what you wanted, if you can get it to compile without warnings. But the use of castings again compromises the static analysis when it comes to proving correct code.

    55. Re:because by EkriirkE · · Score: 1

      Perhaps OP just wanted to initialize post with "first" so later on the post could be re-pointed to another string "rebuttal".

      --
      from 09 F9 11 02 9D 74 E3 5B D8 41 56 C5 63 56 88 C0
      to 45 2F 6E 40 3C DF 10 71 4E 41 DF AA 25 7D 31 3F
    56. Re:because by Joce640k · · Score: 1

      Inmos Transputer was one...

      --
      No sig today...
    57. Re:because by Jonathan+S.+Shapiro · · Score: 1

      Of course it's a cluster. It runs on his microwave, his refrigerator, and his lawn sprinkler controller.

      --
      Jonathan S. Shapiro (The EROS Guy)
    58. Re:because by Anonymous Coward · · Score: 0

      Just imagine a Beowulf cluster of microwave ovens!

  2. One good reason... by Anonymous Coward · · Score: 5, Insightful

    It's not the bloated obscenity that is C++.

    1. Re:One good reason... by serviscope_minor · · Score: 3, Insightful

      It's not the bloated obscenity that is C++.

      C++ is not a bloated obscenity. It is an excellent language.

      I am not claiming it is a language without warts, but I challenge any one who modded the parent post up to provide a coherent argument as to why C++ is bloated and what features you could therefore remove without detracting from the effectiveness of the language.

      --
      SJW n. One who posts facts.
    2. Re:One good reason... by AuMatar · · Score: 5, Interesting

      I like C++, but I can think of a few. Lets ignore for the moment things like macros that are outdated in C++ and kept for C compatibility. We can easily get rid of:

      *Value templates.
      *Diamond inheritance (just make it illegal)
      *The entire algorithms part of the STL. Nobody uses it and it makes for unreadable code (keep the container classes, of course)
      *Kill either structs or classes. We don 't need both, with one being syntactic sugar to change the default visibility on the other
      *The iostream libraries. I don't think I've ever seen code that didn't say fuck that and just use C style stdio. They're clunky.

      That's off the top of my head, without going into things we could do better. And I like C++, it's my preferred language. The real argument here is even though C++ is bloated, it's far from the worst that way. Perl takes that crown, with it's 500 special variables. And the people who complain about C++'s bloat generally like Python or Ruby, which are both just as bloated as C++, without the bonus of it's simplicity.

      --
      I still have more fans than freaks. WTF is wrong with you people?
    3. Re:One good reason... by Anonymous Coward · · Score: 0

      C++ is a reasonable programming language but to so good as a religion

    4. Re:One good reason... by Anonymous Coward · · Score: 0

      Or C#

    5. Re:One good reason... by bluefoxlucid · · Score: 5, Interesting

      Compare C++ to Objective-C. You might dislike the syntax of Objective-C some, but it has clear advantages:

      • It is a strict superset of C: C compiles as Objective-C (C++ doesn't, since structs have a different syntax, among other things)
      • More importantly, it is runtime-resolved. That means you can expand Objective-C classes without breaking the ABI; in C++ you can't add members to classes, at all. Class members can be in different libraries, and in different header files (a "private" member is one not exposed in the API, but you COULD access it directly by defining it or including the header for it).
      • The mangling in C++ is a serious pain and makes loading C++ libraries and programs retardedly slow.
      • Swizzling (you can replace members of classes at runtime--not just inherit, but actually overload class members) makes the language quite a bit more flexible.
      • Operator overloading and templates are an abomination, and don't exist in Objective-C.

      We can all supply better languages for a purpose; Objective-C and C++ have the same purpose (an object oriented general purpose native compiled mid-level programming language), and so this comparison is relevant. Comparing to Java or Python or C#.NET would be irrelevant.

      A loose argument can be made that Objective-C is better because of its much better polymorphism features--the main point of an object oriented language. Objective-C does indeed supply much more flexible, more useful polymorphism; C++ class inheritance is pretty rigid because of its rigid ABI. Objective-C's run time resolution enables this, and I would admit that run time resolution of class objects is a bit slower ... if it wasn't optimized by cache (i.e. resolve the first time on demand and build the PLT) AND if C++ class member mangling didn't make actually building the PLT at load time so god damn slow. Two points to Objective-C.

      Objective-C doesn't have operator overloading. Operator overloading is often claimed as a negative feature because it makes code hard to read. The effective argument AGAINST operator overloading is is that everyone is used to the 'cout >>' and 'cin

      The biggest argument for operator overloading is really that nobody uses it, so we're all familiar with the corner case syntax in the standard library. Think about that: the biggest argument for it is that it never gets used.

      Also, Objective C has reference counting with cycle detectors and all. Garbage collection is a limited feature (you can create garbage collected objects intentionally).

      It's actually relatively easy to argue that C++ is an abomination. It's not unexpected either: it's an old language, and an OOP shim hacked on top of a well-designed mid-level language. That C is so well designed is surprising; but then it is the legacy of assembly, PASCAL, FORTRAN, and BASIC. COBAL is circa 1959, BASIC circa 1964, C circa 1972, C++ circa 1984. C++ had only Smalltalk to learn from, really, and was trying to be C with Classes.

    6. Re:One good reason... by morcego · · Score: 1

      It's not the bloated obscenity that is C++.

      C++ is not a bloated obscenity. It is an excellent language.

      I am not claiming it is a language without warts, but I challenge any one who modded the parent post up to provide a coherent argument as to why C++ is bloated and what features you could therefore remove without detracting from the effectiveness of the language.

      Actually, the language itself is not bloated. Most of the C++ compilers, are. Anyone who ever coded with a real pedantic C++ compiler (IBM's xlC is an example) knows what I mean.

      It always infuriated me that most C++ compilers will happily accept printf() as valid.

      --
      morcego
    7. Re:One good reason... by serviscope_minor · · Score: 4, Insightful

      *Value templates.

      What are value templates? If you mean things templated on integers, then I respectfully disagree. I use some very nice small-vector/matrix linear algebra libraries which would be pale shadows of themselves without templating on integers.

      *Diamond inheritance (just make it illegal)

      Is it a big problem? I think I had a design once where it made sense, but I can't for the life of me remember even what the domain was.

      The trouble with interfaces is that you often end up having to duplicate code because you can't pull in extra stuff like you can with inheritance.

      *The entire algorithms part of the STL.

      No way! I, for one like things like sort (and related), heap, nth_element (one of the very few language std libraries with this O(n) algorithm!), permute, random_shuffle, binary_search (and related), set_union (and related), min/max, min/max_element, equal, swap, and a few others.

      for_each is pretty useless, annoying and unclear.

      Many of the others are generally a bit more useful now with lambdas.

      The algorithms part of the STL is one of my favourite things, and something I really miss when going to other platforms.

      Kill either structs or classes.

      I think that's pretty harmless as these things go. For program structure, I use class, since I want everything private by default (for encapsulation). For template programming, the public-by-default struct is useful for since one often has many tiny structs.

      It's a small oddity, but it must add positively 5 or 6 lines to the compiler.

      *The iostream libraries. I don't think I've ever seen code that didn't say fuck that and just use C style stdio. They're clunky.

      Well, I like the type safety of the C++ library. The formatting stinks and is really painful to use. I ended up writing/finding a few helpers, e.g. ones that use printf style formatting (but with safety) where necessary.

      I've actually got pretty used to it. I find having the variables inline in the positions they appear in the output now easier to follow than jumping between a format string and list of variables.

      I agree that other languages are more bloated, but I think that if you removed any feature you would lose something significant.

      --
      SJW n. One who posts facts.
    8. Re:One good reason... by betterunixthanunix · · Score: 3, Interesting

      what features you could therefore remove without detracting from the effectiveness of the language.

      Exceptions -- I personally like exceptions, but exceptions in C++ are terrible and not necessary. C++ exceptions have the following problems:

      1. No clearly defined exception type -- you could potentially catch something that has no descriptive string, no information about the stack, etc.
      2. Double exception faults. This is a subtle problem but one that seems to be easier to trigger in C++ than other languages, and one that could be fixed by changing how exceptions are handled. For those who are not familiar, exceptions that propagate out of a destructor cause abort() to be called if the destructor was called as part of the stack unwinding process for another exception. If I wanted to call abort() when errors occurred, I would not bother with throw statements, I would just call abort().

        Incidentally, the problem here is the order in which things happen. Exceptions should be caught before the stack unwinding process, which guarantees that the handler will execute before another exception is called. This also allows for "restarts" i.e. the ability to resume execution from the point where an exception was thrown, which might make sense (e.g. for exceptions that indicate some non-critical function could not be performed, which should not prevent a critical function from completing).

      I have also seen quite a few large C++ projects that simply ban exceptions, because they wind up creating more problems than they solve.

      --
      Palm trees and 8
    9. Re:One good reason... by Tyler+Durden · · Score: 2

      The biggest argument for operator overloading is really that nobody uses it, so we're all familiar with the corner case syntax in the standard library. Think about that: the biggest argument for it is that it never gets used.

      Also, Objective C has reference counting with cycle detectors and all

      Smart pointers are used in C++ to take care of reference counting. And dereferencing a smart pointer is achieved by operator overloading "->" .

      I can remember back when I was reading up on Objective-C about how at that time the counts had to be handled manually with "retain" and "release". My God did that look clunky when compared to the automatic handling of reference counts with RAII in C++. I'm not up on the new handling of Objective-C reference counting though.

      Not familiar with how Objective-C does cycle detection. Can you provide a citation?

      --
      Happy people make bad consumers.
    10. Re:One good reason... by Anonymous Coward · · Score: 1

      While everything you say is surely true from your point of view, there are people with other needs. For instance, I'm doing high-performance computing stuff, which, among other things, involves a fair amount of matrix operations. Operator overloading is certainly used, and improves readability quite a bit. Still, in the end I'd probably not care too much about that.

      Where C++ really shines (compared to Objective C) is producing high-performance code. In the most critical places of the code, plain (statically linked) function calls can kill performance, so forget about any runtime stuff there. OTOH C++ templates really shine here: I can pass parameters and functors which are resolved at compile time (and therefore can be inlined). (C++ templates are probably also the #1 reason for preferring CUDA (=C++ compiler) over OpenCL (C shaders) for GPU computations.)

      Sure, C++ is not perfect, but until a different (procedural) language shows up with the same meta-programming capabilities and the possibility to mix low-level code with some high-level OOP stuff, I'm sticking to C++.

      (Also, what's the deal with having to send "destroy" (or whatever) messages to Objective C objects manually? C++ automatic destructors FTW! ;-) )

    11. Re:One good reason... by stanlyb · · Score: 1

      Tell me about. The only OOP language without virtual constructors. WTF???

    12. Re:One good reason... by Tough+Love · · Score: 1

      C++ is not a bloated obscenity. It is an excellent language.

      C++ is an excellent language and a bloated obscenity at the same time. Much like C in its day.

      --
      When all you have is a hammer, every problem starts to look like a thumb.
    13. Re:One good reason... by 91degrees · · Score: 3, Insightful

      Operator overloading and templates are an abomination, and don't exist in Objective-C.

      What's wrong with operator overloading? What if you happen to want a vector or matrix class, or a complex number class? Seems to be a limitation.

      But, the nice thing about C++ is the RAII. Create an object on the stack, and the constructor is called. Function ends, object goes out of scope, destructor is called. Useful for locks. Can also implement timers, resource counting, and of your class is well behaved, you don't need to worry about resources.

    14. Re:One good reason... by stanlyb · · Score: 3, Informative

      And don't forget, the only reason for Objective-C to have these features at run-time is also the only reason why Obj-C is 10 times slower than any other language.

    15. Re:One good reason... by serviscope_minor · · Score: 4, Interesting

      * It is a strict superset of C: C compiles as Objective-C (C++ doesn't, since structs have a different syntax, among other things)

      I've never had trouble pulling C headers into a C++ compiler. Problems can exist, I suppose, but are very rare and easy to work around.

      * More importantly, it is runtime-resolved.

      Or, if you prefer, that's a huge disadvantage. It makes things very, very slow since all sorts of useful optimizations are not possible. If C++ used nothing but dynamic binding, I'd have to stick to C.

      in C++ you can't add members to classes, at all.

      That is a wart with C++. If you pimplify your classes properly, you don't break the ABI. Since it's such a common idiom, it would be really nice if there was compiler support to make it trivially easy.

      * The mangling in C++ is a serious pain and makes loading C++ libraries and programs retardedly slow.

      How so? The mangling gives functions funny long names, but they appear to the linker as just functions with long names, and behave the same way as C programs. I don't recall ever being bitten by this...

      * Swizzling (you can replace members of classes at runtime--not just inherit, but actually overload class members) makes the language quite a bit more flexible.

      That's a potentially useful flecibility.

      * Operator overloading and templates are an abomination, and don't exist in Objective-C.

      You made coherent arguments up to this point, where you basically revert to saying it's bad because you say so. If you use + to add ints and + to add floats in ObjC, then you aren't completely against overloading. Templates and overloading are two of the best features of C++.

      I really don't see how compile time hackery (templates) is inferior to run-time swizzling in ObjC.

      Without templates, there can be no good container libraries.

      Without operator overloading, writing intuitive mathematics libraries (for example) would be impossible.

      A loose argument can be made that Objective-C is better because of its much better polymorphism features--the main point of an object oriented language.

      C++ isn't a objected-oriented language. It's a multi-paradigm language where object-orientation is one of the paradigms supported. You're ignoring all other facets of C++.

      The biggest argument for operator overloading is really that nobody uses it, so we're all familiar with the corner case syntax in the standard library. Think about that: the biggest argument for it is that it never gets used.

      On what grounds is that the biggest argument for it? I use it all the time. I use olperator> on streams. I use + to concatenate strings. I, personally use + to add all sorts of things (like ints, floats, Vectors, Matrices, automatic differentiation types, an occasionally complex numbers). I use operator= all the time to assign one container to another.

      So, your point is basically wrong. I and many others use operator overloading all the time to do useful things, and make stuff clearer and simpler.

      Also, Objective C has reference counting with cycle detectors and all. Garbage collection is a limited feature (you can create garbage collected objects intentionally).

      C++ as they say doesn't need garbage collection as it produces very little garbage. Garbage collection is very nice when you have long lived mutable cyclic datastructures. For all other cases, the arguments for and against are much more subtle.

      Personally, I fund deterministic destruction useful. I find it much easier to run out of memory in Java compared to C++ when dealing with large datasets.

      It's actually relatively easy to argue that C++ is an abomination.

      I beg to differ: you have been unable to argue that so far.

      --
      SJW n. One who posts facts.
    16. Re:One good reason... by serviscope_minor · · Score: 2

      C++ is an excellent language and a bloated obscenity at the same time.

      OK, I'll accept that. It sucks, but less so than all other competing languages. Just like operating systems really.

      --
      SJW n. One who posts facts.
    17. Re:One good reason... by AuMatar · · Score: 5, Insightful

      Value templates- yes, templating on the value, rather than the type. It's an extremely niche use case that causes difficult to read code and provides little in the way of benefits. I doubt even 5% of the user base knows it exists. Kill it.

      Diamond inheritance- it isn't used much, but when it is it's a problem. Because you don't know when the common base class will be initialized, or which constructor will be called by what values. Make it illegal to solve those problems (or add it to the specification)

      STL algorithms- sorry, totally disagree. The entire thing is a horrible hack based on using constructors to make quasi-first order functions. They were never meant to work like that. At best it's confusing, at worst it's unreadable and hard to debug. I bounce any code review I see using them. Worse, it encourages people to make more code like that, which tends to be done worse and be even more unreadable and frequently just wrong (generic programming has a lot of gotchas). I'd rather see the whole thing killed.

      Structs vs class- it is pretty harmless, but we're talking bloat. It's bloat. There's no reason to have both. I wouldn't say this is something that has to be fixed, but it's silly to have the two of them.

      Yup, I stand by my original opinion- all of these could be cut with no real loss to the language. Then again, if I were writing my own language I'd take C, add constructors, destructors, and C++ style syntax for member functions, add container classes, and call it perfect.

      --
      I still have more fans than freaks. WTF is wrong with you people?
    18. Re:One good reason... by Anonymous Coward · · Score: 0

      The biggest argument for operator overloading is really that nobody uses it, so we're all familiar with the corner case syntax in the standard library. Think about that: the biggest argument for it is that it never gets used.

      Very amusing. Just the build-in number-types would need ten or more different operators in C/C++. Another ten to subtract, multiply, .... Complex numbers would double that. Matrices would need an unlimited number.

    19. Re:One good reason... by serviscope_minor · · Score: 2

      There are problems with C++ exceptions (there's a current thread on comp.lang.c++.moderated about double faulting.

      I would agree that they're a long way from perfect, but they capture probably 99.9% of the use cases perfectly. You can always not use them for the other .1%. Most of the time they ensure that resources are freed when an error occurs without the need to write lots of tedious and error prone error checking code.

      Organisations that ban exceptions are frankly being silly.

      You do mention that one problem is a lack of stack information. The trouble is that keeping the stack in tact would seriously hobble the optimizer. After a few passes of inlining, code deduplication, loop unswitching, common subexpression elimination and scheduling, there is, at best a rather tenuous relationship between the generated code and what shape you think the stack ought to have.

      --
      SJW n. One who posts facts.
    20. Re:One good reason... by betterunixthanunix · · Score: 1

      It sucks, but less so than all other competing languages that are popular among schools

      FTFY. In my opinion, Common Lisp is a competing language (both are multi-paradigm, both can be compiled directly to machine code, both have seen plenty of use in large projects, etc.) but it beats the pants of C++. How do you get multiple dispatch in C++? Why do you have to manage the allocation and deallocation of the lexical environment when you create a closure in C++11? Why can exceptions cause programs to abort in C++? Why can a C++ function claim to return something, but never actually have a return statement (which can cause things to become completely unpredictable in the case where you were supposed to return an object value where the destructor is virtual)? None of these things are problems in Common Lisp.

      --
      Palm trees and 8
    21. Re:One good reason... by Tough+Love · · Score: 1

      The biggest argument for operator overloading is really that nobody uses it

      You haven't written any vector code have you.

      --
      When all you have is a hammer, every problem starts to look like a thumb.
    22. Re:One good reason... by Anonymous Coward · · Score: 0

      You will hate the performance though. Objective-C does a lot of dynamic things that make it slower than C++ or C.

      I sort of view Objective-C as a scripting language compared to C/C++. Yes, I know it's not really but some of the sugar it provides is very scripty and slow.

    23. Re:One good reason... by serviscope_minor · · Score: 3, Interesting

      Value templates- yes, templating on the value, rather than the type. It's an extremely niche use case that causes difficult to read code and provides little in the way of benefits. I doubt even 5% of the user base knows it exists. Kill it.

      I think you are underestimating the number of people who use it indirectly.

      I'm in the 5% who use it directly, and it is an invaluable tool which gives C++ a massive advantage over other languages. Otherwise, it is very useful inside metaprogramming, which is the key to making easy to use (not easy to write) libraries.

      Besides how is it hard to read?

      STL algorithms- sorry, totally disagree. The entire thing is a horrible hack based on using constructors to make quasi-first order functions.

      I'm not entirely sure I follow. How do constructors enter into it?

      I bounce any code review I see using them.

      What do you use to sort data? What do you do when you want a heap, or want to perform a set difference or some such operation?

      Yup, I stand by my original opinion- all of these could be cut with no real loss to the language. Then again, if I were writing my own language I'd take C, add constructors, destructors, and C++ style syntax for member functions, add container classes, and call it perfect.

      So, you would have (presumably) type generic container classes?

       

      --
      SJW n. One who posts facts.
    24. Re:One good reason... by betterunixthanunix · · Score: 2

      Most of the time they ensure that resources are freed when an error occurs

      Except that freeing resources might cause an exception to be thrown (see, for example, the fclose manpage; note the number of errors that fclose might return, and now imagine exceptions being thrown for those errors), which is seemingly innocent (after all, it is an error case) but which is practically guaranteed to create a double exception fault if any destructor fails to catch all exceptions.

      Organisations that ban exceptions are frankly being silly.

      Not really; I have heard several software engineering researchers say that exceptions are the completely wrong approach for high-integrity software, and that the right approach is to use return values and to mandate that something be done with the return value. Even without the problems with C++ exceptions, the entire design of exceptions is problematic -- your program basically branches to some totally unknown place, and the only way to figure out where that place is is to actually throw an exception (compare with overridden methods in objects, where you can determine what method will be invoked by checking the object type). I personally disagree and think that exceptions are a more pragmatic way to handle things, since we cannot all sit down and write proofs of correctness for all of our code, but these guys are experts in software engineering, so their opinion is at least worth considering.

      The trouble is that keeping the stack in tact would seriously hobble the optimizer. After a few passes of inlining, code deduplication, loop unswitching, common subexpression elimination and scheduling, there is, at best a rather tenuous relationship between the generated code and what shape you think the stack ought to have.

      Which is solved by resolving the exception handler before destroying the stack. When that happens, I can just examine the stack exactly as it was when the exception was thrown. It also allows the exception handler to make a decision about whether or not the stack should be destroyed i.e. allowing the program to continue execution from the point where the exception was thrown.

      --
      Palm trees and 8
    25. Re:One good reason... by turgid · · Score: 1

      And what happens to your nice RAII objects on the stack when another method further down throws an exception?

    26. Re:One good reason... by Anonymous Coward · · Score: 0

      I dare you to know, master and be able to explain every little feature of C++.
      If you can't (and I think nobody really does), then we can safely say it's bloated. You challenge people to find a single feature that could be removed from C++? But can you even remember them all? So what's the point?
      Heck, C++ is even far from being the best OOP language.
      In my opinion, a programming language, as opposed to a spoken language, should not allow any ambiguous expression and thus can't be too "prolific". Niklaus Wirth always got that right. So anyone telling me that the beauty of C++ is that you don't need to know all of it - I just think it's bullshit.
      Fact is, a whole lot of languages have emerged over the past decades, but not a single one did as well and lasted as long as C. A lot of them have disappeared.
      Another fact is that 99% of "C++ programmers" I ran into can't write proper C, to the point that it's frightening, because this is when you realize they can't write proper C++ (whatever that may be) either.

    27. Re:One good reason... by serviscope_minor · · Score: 2

      The compiler neatly destructs if for you and cleans up all the resources. It's very nice, you should try it sometime.

      --
      SJW n. One who posts facts.
    28. Re:One good reason... by Short+Circuit · · Score: 1

      I am not claiming it is a language without warts, but I challenge any one who modded the parent post up to provide...

      And lose their mod points? Dude!

    29. Re:One good reason... by serviscope_minor · · Score: 1

      Except that freeing resources might cause an exception to be thrown

      I'm aware of that and the long-running c.l.c++.m thread about it.

      I didn't claim there weren't flaws with the system. If you need to deal with errors in fclose(), then call .close() on your class, before it gets destructed, or pass in the class at a higher level.

      Basically, if you have a relatively rare case when exceptions don't fit the bill, then you can opt not to use them and revert to manual error checking.

      Not really; I have heard several software engineering researchers say that exceptions are the completely wrong approach for high-integrity software, and that the right approach is to use return values and to mandate that something be done with the return value.

      The trouble is that you have to do the right thing every time. Resource leaks were the bane of C programmers. These are basically removed with the input of no additional effort on the part of the programmer in C++. Perhaps, in the highest integrity systems where everyone has their code reviewed by multiple people, not using exceptions is better.

      Which is solved by resolving the exception handler before destroying the stack. When that happens, I can just examine the stack exactly as it was when the exception was thrown.

      No, you can't: you missed the point of what I was saying. The optimizer mushes things up so much that even without exceptions, the stack is almost certainly not what it looks like in your program. The current instruction pointer may very well not meaningfully correspond to a line of source code.

      --
      SJW n. One who posts facts.
    30. Re:One good reason... by Short+Circuit · · Score: 2

      Yup, I stand by my original opinion- all of these could be cut with no real loss to the language. Then again, if I were writing my own language I'd take C, add constructors, destructors, and C++ style syntax for member functions, add container classes, and call it perfect.

      So do it. You wouldn't be the first person to create a language more to his liking, believe me. I've seen dozens, if not hundreds, of programming languages which originate from a developer liking some features of another language, but disliking others.

      You clearly have strong opinions; stop writing essays and start writing code! (Or write essays to form a spec, and then code. I see that, too.)

    31. Re:One good reason... by turgid · · Score: 1

      What if you have pointers to objects on the stack?

    32. Re:One good reason... by Anonymous Coward · · Score: 1

      I'm sorry, just because you are too stupid to use multiple inheritance, GOTO, etc, doesn't mean everybody has to be forced into your Playmobil interface. The world is not a tree. It’s a graph! You can't force everything into trees!
      If you buy a professional power drill or other tool, you're also expected to know how to use it. You drilling a hole in your foot, doesn't mean we should all switch to hardware store consumer crap.

      The logical conclusion of your argument is essentially MS Bob, Clippy, iDevices, Ubuntu Unity and Gnome 3.
      No fuckin' thanks.

      (I wonder what you would think about what should be made "illegal" in Haskell... Monads? Higher-order functions? Hell, I had a wannabe web developer idiot tell me that the concept of *functions* was too complicated to use in practice! And he was the development team leader of Lycos Germany! [Yeah, I said it!])

    33. Re:One good reason... by Tyler+Durden · · Score: 1

      Absolutely. If a Java coder ever asks you for cases where RAII would be useful, just refer him to every finally block he ever wrote.

      --
      Happy people make bad consumers.
    34. Re:One good reason... by betterunixthanunix · · Score: 1

      I didn't claim there weren't flaws with the system. If you need to deal with errors in fclose(), then call .close() on your class, before it gets destructed, or pass in the class at a higher level.

      Except that the only safe way to do that is to never have a local object value, smart pointers included. You cannot insert calls to a specific member function into the stack unwinding process, so calling .close() is irrelevant -- the destructor for the class will be called, and if the destructor propagates an exception, the program will halt.

      Basically, if you have a relatively rare case when exceptions don't fit the bill, then you can opt not to use them and revert to manual error checking.

      Except that it is not a "relatively rare" case. Basically, if you ever create a local object value, you have to hope that no exceptions can propagate out of the object's destructor. Maybe you consider local objects to be "relatively rare," but remember that smart pointers, proxy objects, etc. all count (and those are common patterns). Either you forbid exceptions or you mandate that all destructors catch all exceptions, and neither case adequately handles errors (the former is better).

      No, you can't: you missed the point of what I was saying. The optimizer mushes things up so much that even without exceptions, the stack is almost certainly not what it looks like in your program. The current instruction pointer may very well not meaningfully correspond to a line of source code.

      So what? The stack is intact and it can be examined; if you have a bug that is triggered by the changes that the optimizer makes to the stack, that is extremely useful in figuring out what is happening. You missed my point; it is not that you can have a "stack trace" as you might in Java, it is that you can see the actual state of the stack between where the exception was thrown and where it was caught. How is that information not useful to have -- what if you have an uninitialized pointer, and the state of the stack left resulting from an optimization is what is triggering the exception?

      How is destroying the entire stack before the exception can be handled helpful?

      --
      Palm trees and 8
    35. Re:One good reason... by friedmud · · Score: 1

      C++ is great for numerical libraries.

      When you really need speed AND you want OOP there is nothing better than C++.

      It turns out that operator overloading is quite useful in these situations as well (like A*b doing a matrix vector multiply).

      However, I would love to have speed AND some of the features of Objective-C that you point out here. Generally when I want things like add members at run-time or swizzling I generally turn to Python instead of Objective-C... but I will say that that kind of stuff doesn't come up much in my day-to-day numerical library work...

      Disclaimer: I maintain and develop several largish C++ numerical libraries as my day job ;-)

    36. Re:One good reason... by 91degrees · · Score: 1

      Depends where the pointers are. But this is the same problem that you'll always get if you have a pointer to an object on the stack. If the lifetime of the object with a pointer is longer than the lifetime of the method then you have problems. This is a problem with all the C family. C, Objective C, and C++. Presumably other languages that don't do garbage collection as well.

    37. Re:One good reason... by AndrewStephens · · Score: 4, Insightful

      Nobody uses everything in C++, I estimate that most programmers only ever use 75% of the language. The problem is that everybody uses a different 75%. For instance, diamond inheritance can be a pain, but is occasionally unavoidable and I am glad it works. STL algorithms are the best part of C++, complex problems reduce down a few lines of code.

      Your one example that is actually bloated is iostreams, which is slow and overkill for almost any program. I wish more C++ text books would ignore iostreams and spend more time on STL.

      --
      sheep.horse - does not contain information on sheep or horses.
    38. Re:One good reason... by Darinbob · · Score: 4, Insightful

      Macros aren't really outdated. Maybe 95% of their uses can be replaced with enums or inline functions, but there are also times where textual substitution can do useful things.

      Templates as a whole are overused and lead to problems, and in particular tend to not co-exist with object oriented styles. Small simple templates I like, but I see them used to completely replicate a data structure which leads to bloat. And the bloat in C++ is not bloat in features as you sort of imply but bloat in the immense size of the executable. Templates really are just a style of textual substitution, except that unlike C macros this is hidden from the programmers who often don't realize how much extra space can be taken up by them if they're not careful. I don't think there are any compilers yet smart enough to determine when two template instantations only needs one copy at run time, and you end up with standard "libraries" where most of the code is in a header file and recompiled often. To be fair you can use templates that do some nice libraries (ie datastructures store void* and the templates just do the type safety checks for you before casting), except that this is contrary to the STL style. I used to like the rogue wave libraries myself.

      You need structs in C++ to be compatible with C. One of C++'s goals is to compile proper C programs and keep compatibility where possible. But if you got rid of the class keyword instead you'd have a revolt. So the typical style almost everyone uses is that struct is used as a plain C struct only, and if you need anything beyond what C can do then you use a class instead. What C++ should have done I think is to enforce that style.

      I agree, iostream is awful. Originally it wasn't too bad in some ways and early on it did a good job of adding some extra type safety to IO. But it always felt like a bit of a kludge. It is nice to have a more generic output destination like a stream buffer but it came saddled with the operator overloading and you needed to know implementation details to do a lot of useful stuff.

      Diamond inheritance is a side effect of C++ never being able to say no. It should have just said "no multiple inheritance". Once it did have mutliple inheritance it should have not allowed the cross pollenization and stuck to a style where multiple inheritance had only mixins or interfaces. But they didn't want to say "no" and figured that they could use a keyword so that the user could do what they wanted. Which resulted in a lot of confusion.

      Actually Ruby is a relatively simple language. A good job of making a textual style of Smalltalk (only with a horrible kludge of blocks). The bloated part may be the Ruby on Rails which is not the same thing at all. Ignoring libraries and looking just at the syntax/semantics of the language then Ruby is much simpler than C++.

    39. Re:One good reason... by UnknownSoldier · · Score: 3, Interesting

      I used to work with a team that produced a professional C/C++ compiler. We used to joke:

      There are two problems with C++
      1. it's design
      2. it's implementation

      As a programming I've come to love the sweet spot 1/2 between C and C++.
      C leads to overly terse code
      C++ leads to over-engineered solutions

      Its too bad the preprocessor is still stuck in the '70s :-( Every year C++ is slowly turning into a clusterfuck LISP implementation by people who don't understand how to write a safe macro meta-language.

    40. Re:One good reason... by AuMatar · · Score: 0

      I don't think I am. Take a survey of average C++ programmers who don't work directly with you on that type of code. See how many of them know they can do that. I actually think 5% is an overestimate. And if that small a percentage actually know about and use a feature, I question how much that feature is worth. Especially when it at best offers a miniscule speed boost over just passing in the number as a parameter.

      Sorry, my mind was slipping. I meant functors, not constructors. Functors are implemented by overriding the constructor of a class to preform an odd type of initialization and then overriding the operator () to do computation. It's an ugly, difficult to understand hack. It completely destroys the idea of what a class is, and for those of us who use type as the center of understnading how code works, it completely fucks us over by throwing dozens of non-types. It's also the basis for how all of the STL algorithms code works. It should never have existed to begin with, and it should die a horrible death.

      Can't say I've ever wanted to perform a set difference. But if I did, there's be a method difference in the class Set, and it would take the second set as a parameter and spit out the result.

      Same with a sort- the class would have a sort function. I would reluctantly not bounce using the sort function of the STL since it's so useful, but it's still not the right way of doing things. And it's much more complex than it should be, since the calling code has to worry about things like passing in comparators, when that should really be the job of the sort function.

      Yes, i would have container classes, they're useful. I wouldn't have any generic algorithms, they tend not to be useful, are easy to make wrong in subtle ways, and the "smarter" you try to be with them the less readable your code is. They're also much less readable- give me a loop over all the indices in an array over an ugly foreach that gets passed a function any day of the week.

      --
      I still have more fans than freaks. WTF is wrong with you people?
    41. Re:One good reason... by Anonymous Coward · · Score: 2, Interesting

      There needs to be a Godwin's Law corollary for MS Bob.

    42. Re:One good reason... by GauteL · · Score: 3, Interesting

      When it comes to STL algorithms, you may have been right before C++11/C++0x. Now, with lambda functions, the standard algorithms are genuinely brilliant. Modern IDEs should support debugging the lambdas as well.

      I honestly don't care if you disagree. There are enough people around that use them extensively and they are not going away. I would most likely bounce your code your code for NOT using STL algorithms if they were the quickest solution.

      I completely agree on struct/class and diamond inheritance though.

    43. Re:One good reason... by Short+Circuit · · Score: 1

      It also allows the exception handler to make a decision about whether or not the stack should be destroyed i.e. allowing the program to continue execution from the point where the exception was thrown.

      Personally, I make that decision by choosing where I put my try...catch blocks.

      Here's pseudocode for a common idiom where I work for opening and parsing internal binary-format files:

      bool ParseFile(fh file_handle)
      {
          bool bRet = false; // try
              m_SomeMember = ReadValue(file_handle);
              m_SomeOtherMember = ReadValue(file_handle);
              m_YetAnotherMember = ReadValue(file_handle);
              m_AndStillAnotherMember = ReadValue(file_handle);
              bRet = true; // catch
          { // Log an error
          }
          return bRet;
      }

      Of there's a failure between those try and catch blocks, I don't give a crap about the rest of the content of the file, or even of any temporary variables I may have created for conditional processing. ReadValue() will throw an exception, no more calls to ReadValue will be made, the catch block will do its own thing, and we'll all be very happy. Well, the user might be pissed his file is corrupt...

    44. Re:One good reason... by Anonymous Coward · · Score: 0, Informative

      http://www.mikeash.com/pyblog/performance-comparisons-of-common-operations-leopard-edition.html

      C++ virtual method call 1.1 ns
      Objective C message send 4.9 ns

      4.9/1.1 ~ 4.5 times slower.

      I don't know where you're getting 10 times slower from.

    45. Re:One good reason... by serviscope_minor · · Score: 1

      What if you have pointers to objects on the stack?

      Then the compiler can't do such a good job of optimization.

      --
      SJW n. One who posts facts.
    46. Re:One good reason... by shutdown+-p+now · · Score: 1

      Value templates.

      Why? They make compile-time computations possible. Okay, so now we kinda sorta have that with constexpr also, but it still doesn't fully cover the same ground.

      *The entire algorithms part of the STL. Nobody uses it and it makes for unreadable code

      People weren't using algorithms only because it was tedious to write functors, and they couldn't be written inline. Now that we have lambdas, algorithms are the way to go. I'm working on a code base that had been using algorithms+lambdas for 2 years now, and it's much clearer than loops.

      The iostream libraries. I don't think I've ever seen code that didn't say fuck that and just use C style stdio. They're clunky.

      Agreed, though we need to replace them with something better rather than just killing them. In particular, now that we have variadic templates, I want an I/O library that has high-performance, typesafe printf out of the box.

    47. Re:One good reason... by shutdown+-p+now · · Score: 1

      If you know your C++, your pointers will be std::unique_ptr's, which will destruct the objects they point to.

    48. Re:One good reason... by Anonymous Coward · · Score: 0

      You forgot that C++ learned object orienting from Simula 67.

    49. Re:One good reason... by Anonymous Coward · · Score: 0

      Try debugging a 10 year old still live C++ project and then try debugging a 15 year old C project if you want to see the bloat C++ has and encourages. The problem with most languages, including C++, is that the designers and implementers of the languages forgot that the logic expressed by the language users will need to be debugged and instead focused primarily on forcing the programmer to use a specific methodology (object, in the case of C++.) With C, as the code ages, problems with the code are not as abstracted away as with C++ and thus can be debugged and fixed much faster.

      As to why C++ is bloated in comparison to C one only needs look at the fact that anything one can do in C++ one can do in C; it's fairly straight forward to write a C compiler as opposed to writing a C++ compiler. C++, as with many other languages, attempting to force good programming on people doing the coding requires additional complexity which, in my book, constitutes bloat.

    50. Re:One good reason... by 0ld_d0g · · Score: 1

      I used to work with a team that produced a professional C/C++ compiler.

      Was this pre c++03 or post?

      Every year C++ is slowly turning into a clusterfuck LISP implementation by people who don't understand how to write a safe macro meta-language.

      Except.. without even more ugly hacks to the preprocessor, there is no way to ensure any kind of tangible "safeness" to the macro system.

      I'd prefer removing obsolete C & preprocessor crap from C++. It would improve the language in every conceivable way.

    51. Re:One good reason... by shutdown+-p+now · · Score: 2

      A loose argument can be made that Objective-C is better because of its much better polymorphism features--the main point of an object oriented language. Objective-C does indeed supply much more flexible, more useful polymorphism; C++ class inheritance is pretty rigid because of its rigid ABI. Objective-C's run time resolution enables this, and I would admit that run time resolution of class objects is a bit slower ... if it wasn't optimized by cache (i.e. resolve the first time on demand and build the PLT) AND if C++ class member mangling didn't make actually building the PLT at load time so god damn slow. Two points to Objective-C.

      All well and good, but increased dynamism of Obj-C also means that it is that much slower - if I remember correctly, any Obj-C message dispatch, even in the best case (i.e. directly handled by the object), is still several times slower than a C++ virtual method call - and most method calls in C++ aren't virtual, and are typically inlined.

      Operator overloading and templates are an abomination, and don't exist in Objective-C.

      Operator overloading is arguable. Every time you have to write something like a.add(b).multiply(c) in Java when working with, say, BigDecimal, you understand why operator overloading was invented. On its own, it's definitely a good feature - it lets you offload a bunch of language semantics to the library. The only harm comes from its misuse, but that is true of practically every language feature.

      Templates aren't even arguable. Due to their lack, Obj-C still doesn't have proper typesafe collections. You could argue that templates are poorly designed in C++, and that something like C# generics would be better, but that again is an issue of convenience vs performance. C++ templates have the advantage of, ultimately, being a lot like turbocharged macros - the code that gets compiled in the end is what you'd write by hand after substituting all template parameters, and so it's just as fast. Templates are what makes C++ std::sort faster than C qsort.

      Also, Objective C has reference counting with cycle detectors and all.

      Obj-C with ARC does not have cycle detection. You have to use weak references to avoid cycles, or otherwise break them up manually.

      C++ has all the same stuff (shared_ptr / weak_ptr), except you decide whether to opt in or not for every object you allocate, and so you don't pay the penalty for every single one. Why would I need to refcount an object that is allocated in a function, and destroyed when it returns?

      That C is so well designed

      Are you serious? #include, insane declarator syntax, struct/union/enum tags, the way it treats mixed signed/unsigned arithmetic, implicit cast from void*... C has so many warts it's not even funny. The only good thing about it is that it's very low level and it exists on every platform, making it a "portable assembler".

      C++ had only Smalltalk to learn from, really, and was trying to be C with Classes.

      C++ has practically nothing to do with Smalltalk. It's actually C with Simula-67 slapped on top (where do you think "virtual" came from?).

    52. Re:One good reason... by gbjbaanb · · Score: 1

      ok, so scrap a load fo useful stuff becuase.... well, I'm not sure why not. Just because you don't use algorithms doesn;t mean no-one else does.

      As for diamond inheritance - I guess you're referring to the diamond 'problem' of multiple inheritance (where your class derives from 2 base classes, each of which derive from a common base class themselves - in such cases, you have to put the virtual keyword in to tell the compiler to take it into account, or you get 2 distinct instances of each base class... which might be what's needed, which is why it's not automatically dealt with by the compiler by default).

      It sounds like you want to just dumb down the language to the point where it's called C#. I think most of your arguments aren't really arguments at all, and you could do a lot better if you really wanted to criticise the language.

      I don;t like a lot of the template complexity now, but then... and this is the big deal, I don't have to use them (and I don't - I feel they don't make for maintainable code) but that doesn't mean they don't have their place in some specialist areas. Of course, if you don;t use a feature, that feature doesn't get in your code - so the only thing that gets bloated is the compiler, and that's hardly a problem.

    53. Re:One good reason... by Anonymous Coward · · Score: 1

      C++ is so complicated that even the writers of C++ compilers struggle to understand the standard in full. (Just look in the G++ changelogs for plenty of examples of this!)

      It is literally unbelievable that anyone could look at an arbitrary chunk of non-trivial C++ code and be certain they could explain exactly what it does (and why) without potentially spending hours researching it.

      How can such a language not be bloated?

      I will not deny that, in the hands of a master, it can be used to write performant, robust, and maintainable code quickly; indeed it is probably better than any other widespread language in this regard. But think how many of the other programmers you know are actually masters, and then you may grasp why I do not advocate the use of C++.

    54. Re:One good reason... by shutdown+-p+now · · Score: 1

      No clearly defined exception type -- you could potentially catch something that has no descriptive string, no information about the stack, etc.

      std::exception is it. Granted, not everyone actually uses it, but you should.

    55. Re:One good reason... by eruci · · Score: 2

      i love C and Perl. for two opposing reasons.

      --
      artificial intelligence is no match for natural stupidity.
    56. Re:One good reason... by Anonymous Coward · · Score: 0

      I have heard several software engineering researchers say that exceptions are the completely wrong approach for high-integrity software, and that the right approach is to use return values and to mandate that something be done with the return value.

      I think the creators of the Ada language would beg to differ. Ada was specifically designed for high-integrity systems, though the mechanism in Ada is (unsurprisingly) stricter than in C++.

      - T

    57. Re:One good reason... by Anonymous Coward · · Score: 0

      I find having the variables inline in the positions they appear in the output now easier to follow than jumping between a format string and list of variables.

      Yep, it's really neat. Oh, did I mention we're releasing your program in Korea next week and we need to localize all those strings? Yeah, the words are going to be in a different order too. Good luck!

    58. Re:One good reason... by shutdown+-p+now · · Score: 1

      Either you forbid exceptions or you mandate that all destructors catch all exceptions

      Keep in mind that all destructors are now implicitly noexcept in C++11 unless specifically told otherwise.

    59. Re:One good reason... by russotto · · Score: 1

      It's not the bloated obscenity that is C++.

      Got it in one.

    60. Re:One good reason... by Rob+Riggs · · Score: 1

      Wow -- get rid of algorithms? You, sir, have not been paying attention to C++ lately. Half of Boost is yet more algorithms -- range adapters, string algorithms, RNG algorithms, statistical algorithms, graph algorithms, and numerical algorithms. Far from making the code unreadable, done right it makes the code more beautiful and concise.

      One near certainty when looking at C++ code is that if the code does not "#include <algorithm>", it is invariably slow and/or buggy.

      --
      the growth in cynicism and rebellion has not been without cause
    61. Re:One good reason... by gman003 · · Score: 1

      You do know that you can just not use features, right?

      I don't even know what Value Templates are, so I'm pretty sure I've never used them.

      I've never used diamond inheritance. Hell, I rarely use any sort of multiple inheritance.

      I've never used the STL algorithms, although I'm tempted to try sometime just to see if it's as bad as everyone makes it out to be.

      I do mix structs and classes, but mainly for readability. My classes are proper, encapsulated objects - no public variables, full of get() and set() methods. My structs are essentially combined variables - if I were to make a coordinate "type", I would do so as a struct. While I could get the same functionality from just classes, I like having that extra bit of "wait, can I just grab that variable and mess with it, or do I need to use getter/setter methods?" implicit documentation.

      The iostream libraries are indeed ugly and never used, and should be cast into the fires of /mnt/doom.

    62. Re:One good reason... by bstamour · · Score: 2

      Value templates can be great. Have a look at std::array. Under the hood it's just a static C-style array (take a look at the generated assembly, on a decent compiler there's zero added overhead), but it remembers it's size as it's baked into the type itself. So it gives us all the speed of a C-style stack-allocated array of N items, plus removes the hassle of having to pass the size around as an extra parameter to functions. Finally, if you really want to be safe, you can use the .at( ) member function for range-checked access. The operator [ ] is overloaded of course for direct access, in case you need that too. This functionality would be impossible without the ability to use std::size_t as a template parameter.

    63. Re:One good reason... by haruchai · · Score: 1

      +2 Informative

      --
      Pain is merely failure leaving the body
    64. Re:One good reason... by turgid · · Score: 0

      Ah, right, of course.

      And presumably "*" is overloaded? And how do you know whether a pointer is smart or not? Presumably you look at the #includes? Right. What if someone uses a different smart pointer library/template/whatever?

      And what about new and delete and arrays, vectors, and all that jazz?

      So why don't they just make pointers behave like that in the first place? Oh, because that would break backwards compatibility with C source (you are meant to have swallowed the pill and be compiling all your C code in your C++ compiler, and modify it where its broken)... even although the language isn't a strict superset of C and you can't rely on the behaviour of the compiled code to be the same...

      So why don't you just forget C++, keep your "old" C code, and use a better high-level language for the OOP stuff, calling the low-level C stuff where required?

      But, but, but...

      C++ is getting more like Religion as time goes on.

      There are two types of people in this world: those that pretend to understand C++ and those that don't pretend that they don't.

    65. Re:One good reason... by mzs · · Score: 1

      I do realtime embedded. I made a kernel that had C++ support and it would crash on boot. The watchdog timer would fire before all the C++ support initialization routines would finish. I had to disable the watch dog timer temporarily. I think it was the exception and io streams initialization code that was the culprit. The whole exceptions thing can be bloated depending on implementation to varying degrees. But in the end what is more bloat (checking return values all the time or exception frames handling all the time) I do not know.

    66. Re:One good reason... by Anonymous Coward · · Score: 0

      Objective-C doesn't have operator overloading. Operator overloading is often claimed as a negative feature because it makes code hard to read. The effective argument AGAINST operator overloading is is that everyone is used to the 'cout >>' and 'cin

      I can't comment on Obj C as I have no experience using it - but if you do get rid off operator overloading then do it consistently and not the Java-way (where overloading operators is impossible but "+" is used for string concatenation nevertheless).

    67. Re:One good reason... by Rostin · · Score: 1

      Disclaimer: I maintain and develop several largish C++ numerical libraries as my day job ;-)

      Sorry to blitz you like this, but...

      I'm a PhD student in chemical engineering at a "Top 5" department in the US. I'll finish in the next few months. I use atomic-scale simulations to study metal alloy surfaces for use as catalysts. The basic method is, I create a library of small model surfaces, calculate their energies using density functional theory, and then fit a model Hamiltonian to those results. I can use the Hamiltonian to do things like find the ground state configuration of an alloy or perform Monte Carlo simulations to predict finite temperature properties. I've also worked a little on predicting the shapes of metal clusters using genetic algorithms. I use a canned code to do the DFT calcs, but everything else is custom written in C++ and python. I'm also passingly familiar with some of the more modern flavors of Fortran.

      One of the things I've learned (confirmed, really) during graduate school is that I really enjoy writing scientific software. I'd go so far as to say that I enjoy developing the tools to do computational research more than the research itself. I'd like to find a post-doc or a full time position at one of the national labs where I could do that. The trouble is, although I've taken and audited a few classes in things like parallel programming, I'm mostly self-taught, so I'm concerned that I don't have the software development chops to make it happen.

      I realize you haven't talked to me or seen my actual CV, but do you think this is a realistic goal?

    68. Re:One good reason... by serviscope_minor · · Score: 3, Insightful

      I don't think I am. Take a survey of average C++ programmers who don't work directly with you on that type of code. See how many of them know they can do that. I actually think 5% is an overestimate. And if that small a percentage actually know about and use a feature, I question how much that feature is worth. Especially when it at best offers a miniscule speed boost over just passing in the number as a parameter.

      Several points:

      Expert-friendly language features enable the creation of better libraries. Library users might not even realise that they are using the advanced features. That doesn't make the advanced features worthless.

      Having fixed sized linear algebra objects yields massive speed increases, not tiny, since the compiler is able to sue stack allocation (which is essentially free) which is vastly faster than malloc/free. Secondly, the optimizer seems much better able to reason about stack allocated objects, giving another large speed increase.

      At best, the speed increase is well over a factor of 10, and I have verified this with benchmarks.

      Functors are implemented by overriding the constructor of a class to preform an odd type of initialization and then overriding the operator () to do computation.

      I think functors just (in general) overload operator(). Nothing special is necessarily done with the constrtuctor.

      It's an ugly, difficult to understand hack. It completely destroys the idea of what a class is,

      I don't see how: a class is an aggregation of methods and members. C++ allows you to use some OO features with classes if you like, but it isn't necessary. What would you prefer?

      Can't say I've ever wanted to perform a set difference. But if I did, there's be a method difference in the class Set, and it would take the second set as a parameter and spit out the result.

      OK, so how do you store elements of the set?

      What I'm driving at is that in C++ set_difference, etc work on any ordered collection of things. The advantage is that you can choose the container for the collection based on the algorithmic properties you desier (array, RB-tree, linked list, etc).

      Same with a sort- the class would have a sort function. I would reluctantly not bounce using the sort function of the STL since it's so useful, but it's still not the right way of doing things. And it's much more complex than it should be, since the calling code has to worry about things like passing in comparators, when that should really be the job of the sort function.

      So, every container class needs to have it's own sort function? If so, then they would likely share a lot of common code. Is that whay you propose?

      --
      SJW n. One who posts facts.
    69. Re:One good reason... by Anonymous Coward · · Score: 0

      STL algorithms are the best part of C++, complex problems reduce down a few lines of code.

      The one's that are actually non-trivial are nice. But take for_each for example: That one is 100% useless without lambdas, and makes understanding the code a real pain compared to the hand-written loop.

    70. Re:One good reason... by shutdown+-p+now · · Score: 1

      And presumably "*" is overloaded?

      Sure. That is implied by the definition of smart pointer. Ditto for ->.

      And how do you know whether a pointer is smart or not?

      std::unique_ptr and std::shared_ptr are smart. T* is not smart. There shouldn't be any other kind.

      What if someone uses a different smart pointer library/template/whatever?

      What if someone writes code in a way that it can be readily submitted to IOCCC?

      I mean, C++ - like C - lets you shoot yourself in the foot just fine if you really want to. But if you don't, it also gives you everything you need to avoid that with minimum hassle. So don't.

      And what about new and delete and arrays, vectors, and all that jazz?

      What about them? new is orthogonal to smart pointers - you still allocate objects with new, you just let smart pointer take care of their lifetime. And both smart pointers in the standard library support both scalars and vectors, no need to do anything special there.

      You shouldn't ever need to write delete if you're writing C++ the right way, except if you're writing your own smart pointers (which you again shouldn't be doing). Consider it a legacy feature.

      Vector is unrelated. It's a class representing a dynamically resized array, which is an abstraction completely different from a pointer. It is rather unfortunate that C invites confusion between arrays and pointers due to the former decaying to the latter in some contexts. Gladly, this is not the case with more advanced C++ abstractions - a pointer is a pointer, and a vector is a vector. You can have a pointer to a vector if you want, but be explicit.

      So why don't they just make pointers behave like that in the first place?

      Because you don't want every pointer to try to delete what it points to. This can also be achieved by having every pointer do reference counting (as in Obj-C ARC), but that would be relatively expensive, and in C++ you don't pay for things you don't need.

      So why don't you just forget C++, keep your "old" C code, and use a better high-level language for the OOP stuff, calling the low-level C stuff where required?

      Because no other mainstream high-level language offer the combination of power and speed that is offered by C++.

    71. Re:One good reason... by Old+Wolf · · Score: 1

      for_each is pretty useless, annoying and unclear

      I think it's pretty clear:
          list x;
          for_each( begin(x), end(x), bar );

      Hopefully even non-C++ people will realize that this calls bar() once for each of the members of x.

      This is sort of redundant in C++11 because you could just go:
          for( foo &a: x )
              bar(a);

      but for_each allows you to use existing predicates (with for_each_if and so on) ,
      and you can put a lambda expression instead of "bar".

    72. Re:One good reason... by turgid · · Score: 1

      What I meant to say was "pointers on the stack that point to objects dynamically allocated in freestore (on the heap)."

      Oh, and another thing, I once read some punditry that freestore and the heap are different in the context of C++. What is that all about?

      In my day, we had the heap and the stack and we smiled and liked it.

    73. Re:One good reason... by BenoitRen · · Score: 1

      It's actually relatively easy to argue that C++ is an abomination. It's not unexpected either: it's an old language, and an OOP shim hacked on top of a well-designed mid-level language. (snip) C++ had only Smalltalk to learn from, really, and was trying to be C with Classes.

      Replace C++ with Objective-C and this paragraph is still correct. Objective-C is older than you think (1980).

      Meanwhile C++ has become its own language while Objective-C is still a crude hack on top of C.

    74. Re:One good reason... by DamnStupidElf · · Score: 1

      Same with a sort- the class would have a sort function. I would reluctantly not bounce using the sort function of the STL since it's so useful, but it's still not the right way of doing things. And it's much more complex than it should be, since the calling code has to worry about things like passing in comparators, when that should really be the job of the sort function.

      template void sort ( RandomAccessIterator first, RandomAccessIterator last ) might be what you want with no comparison function as a parameter.

      Yes, i would have container classes, they're useful. I wouldn't have any generic algorithms, they tend not to be useful, are easy to make wrong in subtle ways, and the "smarter" you try to be with them the less readable your code is. They're also much less readable- give me a loop over all the indices in an array over an ugly foreach that gets passed a function any day of the week.

      Taking STL sort as an example; what you primarily need to care about is that swap() is efficient for objects of the type you're sorting. Overload it if you have to. for_each is much more readable (and powerful) when using anonymous functions. If anything, the verbosity of C++ function definition is your enemy, not generics. I think C++0x11's trailing-return-type declaration will help immensely.

    75. Re:One good reason... by chgros · · Score: 1

      More importantly, it is runtime-resolved.
      I personally would consider this a disadvantage.
      I like my type-checking at compile-time thank you.

    76. Re:One good reason... by rrohbeck · · Score: 1

      That's the main problem: TIMTOWTDI. The programmer on the team who uses static character arrays and memcpy won't even understand my template code. Yet we both call ourselves C++ programmers.
      Also, C++ has many ways to obfuscate really bad design decisions under an OO veneer. I have seen many class hierarchies that look pretty at the top level but when you drill down the coding horror starts.

    77. Re:One good reason... by Anonymous Coward · · Score: 0

      Well, that's just your own opinion. Many others would disagree, and luckily the C++ standard as well as the standard library have been constructed and ratified by pretty smart people.

      For once, I wouldn't want to live *without* templates on numeric types as well as the - fantastic - STL algorithms.
      Just respect that there are tens of thousands of competent C++ programmers that DON'T share your opinion.

    78. Re:One good reason... by roky99 · · Score: 3, Insightful
      It's clear that you don't really get a lot of this stuff. Despite that, you seem to be in some position where you can review and reject other people's code. Your remarks would be hilarious if I didn't think you were serious. For example:

      Can't say I've ever wanted to perform a set difference. But if I did, there's be a method difference in the class Set, and it would take the second set as a parameter and spit out the result.

      The whole point about generic algorithms is that you only have to write them once and can then use them with all sorts of containers, including ones that might not have been written yet, as long as the containers satisfy the minimal requirements of the algorithm. So for example, the 'set' in set_difference does not refer to the container type - it is a description of what the algorithm does. The algorithm does not demand a set; you can equally apply it to a sorted vector. Furthermore, the two input sequences to set_difference do not even have to be the same type as long as their elements are compatible, so I can apply it to a set of strings and a sorted vector of strings if I want to. By your argument, I would have to have a set class with a difference method, and a sorted vector class with a difference method. And then if I wanted set's difference method to work with sorted vectors and other compatible sequences, how would that work? I would have to write it as some sort of generic member function anyway.

      Same with a sort- the class would have a sort function. I would reluctantly not bounce using the sort function of the STL since it's so useful, but it's still not the right way of doing things. And it's much more complex than it should be, since the calling code has to worry about things like passing in comparators, when that should really be the job of the sort function.

      So what you are saying is that instead of having a sort algorithm implemented once, I need to reimplement that algorithm in every class that I might want to sort. So either I guess that I might want to sort it at the time of writing it or, if I didn't get that right, I have to go back and modify the class. Compare that with the non-intrusive sort algorithm. How is what you are proposing good software engineering practice by any stretch of the the imagination? And I don't understand your point about comparators. In most cases a type you want to sort probably defines a less than operator, which is all you need and you don't need to provide an explicit comparator. It's only when you need to do something special that you need a comparator. How would the sort member function be better?

      Here's a hint: go and look up the word 'orthogonal'. It's a key concept in understanding the STL.

    79. Re:One good reason... by RCL · · Score: 1

      * The mangling in C++ is a serious pain and makes loading C++ libraries and programs retardedly slow.

      How so? The mangling gives functions funny long names, but they appear to the linker as just functions with long names, and behave the same way as C programs. I don't recall ever being bitten by this...

      This is only an issue under Unix, where linking happens at run-time. May also happen under Windows if you begin to carelessly __declspec( export ) whole classes.

    80. Re:One good reason... by Anonymous Coward · · Score: 0

      C++ has all the same stuff (shared_ptr / weak_ptr), except you decide whether to opt in or not for every object you allocate, and so you don't pay the penalty for every single one. Why would I need to refcount an object that is allocated in a function, and destroyed when it returns?

      ARC and Clang do the exact same thing.

      When you have code that looks like,

      - (void)foo {
              Bar *b [[Bar alloc] init]; ...
      }

      The compiler optimizes away the retain and releases.

    81. Re:One good reason... by Deorus · · Score: 1

      While I agree that the standard library is mostly useless (for instance C++11 specifically supports threads but none of the standard containers supports the volatile qualifier (I'm sure someone will comment on this too, and I'll have to demonstrate, again, why volatile is still required for multithreaded development)), some of your points result from a lack of understanding of the language.

      *Value templates.

      As you should have already noticed, raw arrays in C and C++ take integrals as part of their type definition. Thus, without support for integral template arguments, it would not be possible to generically represent them. Beyond this, integral template arguments are also useful for functional metaprogramming in order to, in conjunction with variadic templates, allow the creation of extremely intuitive templates classes and functions. See for example std::array (raw arrays as generic containers with backward compatibility), std::function (generic and abstract support for both function pointers and functors, and the only way to specify a type for a lambda / closure), and the templates constructor for std::thread (accepts a function, a functor, a lambda / closure, and its arguments based on the type of the function passed as the first argument) in C++11. Users are not required to fully understand how templates work in order to take advantage of libraries written with them. You don't need to understand how std::function is implemented in order to use it, just accept that it Just Works.

      *Diamond inheritance (just make it illegal)

      Making diamond inheritance explicitly illegal would force users to understand how the classes that they are inheriting are implemented, an anti-pattern requirement that does not exist now thanks to virtual inheritance, and if you are suggesting removing multiple inheritance altogether, then I disagree on the basis that it is extremely useful in cases of aggregation (protected / private inheritance).

      *Kill either structs or classes. We don 't need both, with one being syntactic sugar to change the default visibility on the other

      We need structs for backward compatibility with C. We need classes to distinguish intent and force people to be explicit about encapsulation if they actually intend to have anything visible to the outside to non-friends, not to mention that just removing classes from the language at this point would be completely unfeasible as it would break a lot of code.

    82. Re:One good reason... by Anonymous Coward · · Score: 0

      Well then it's a good thing Objective C compilers do compile time checking.

    83. Re:One good reason... by shutdown+-p+now · · Score: 1

      Does it also optimize them away when you have an object reference as a field of another object, and their lifetimes are identical?

    84. Re:One good reason... by microbox · · Score: 1

      For me, lambda expressions are the saving grace for C++. You have to do a lot of functional programming to do it well, but once you know, you can never go back. Functional programs are shorter, clearer, simpler to write, and have much more sane code reuse than the almost-mis-feature of inheritance.

      --

      Like all pain, suffering is a signal that something isn't right
    85. Re:One good reason... by Anonymous Coward · · Score: 0

      C++ does have the ability to catch exceptions before the stack is unwound.

      On windows with structured exception handling, plain c programs can register vectored exception handlers which also receive control before the stack is unwound, and can resume the code if they handle the problem.

    86. Re:One good reason... by Anonymous Coward · · Score: 0

      If that object is strongly referenced it will.

      http://adcdownload.apple.com//wwdc_2011/adc_on_itunes__wwdc11_sessions__pdf/323_intro_to_arc_304repeat.pdf

    87. Re:One good reason... by hey! · · Score: 1

      [disclaimer -- it's been years since I use either Objective C or C++.]

      Objective-C doesn't have operator overloading.

      Really? So you can't say both "float f = 2.0 * 3.14.159;" and "int i = 3 * 5;" ? Of course Objective C has operator overloading, because as you say it is a superset of C and *C* has operator overloading. What it doesn't have is *programmer defined* operator overloading. Whether that feature is a good thing depends on the application and the programmer involved.

      If you think I'm just being pedantic, consider the example above. Floating point numbers and integers are very different animals. The binary representation is different. "float * float" has a completely different implementation than "int * int". But both ints and floats are algebraic rings, so it makes sense to have the operations "+" and "*" defined on them. Furthermore, int values (in the computer sense) are supposed to represent integer numbers (in the mathematical sense) and float values are meant to represent real numbers. Integer numbers are a proper subset of real numbers, but *int values* are completely distinct from any float value in its binary representation. Thus C (and presumably Objective C) not only has operator overloading, it has auto-magical type casting (e.g. "float f = 2 * 3.14"), just like in C++. Nobody doubts this feature is a *generally* a good thing (although it can cause bugs like zero testing floats to terminate loops). It's only when programmers are forced to learn about this when they learn C++ that they have conniptions about how loosey-goosey the whole thing is.

      When *programmer defined* operator overloading is used in this way -- defining an operator for an application that is strictly analogous to its original meaning -- I don't see any problem whatsoever with it. Defining "*" and "+" on objects that form an algebraic ring would be a prime example. There's no reasonable argument to be made that programmer defined operator overloading is just what you want in that case. What's questionable to me is overloading an operator for a use which is not quite analogous to it's original purpose. For example using "string + string" for string concatenation and "int * string" for string repetition strikes me as practices that might be questionable were they not common idioms in other programming languages.

      I think more cogent criticisms can be made of C++; particularly its lack of interfaces, and the use of multiple inheritance. The presence of some features (like the virtual/non-virtual function distinction), and the absences of others (threading) are a legacy of the era in which C++ was designed. I'd argue quite brilliant for the needs of the time given the state of experience with OOP at the time.

      I have little doubt that for most programmers on most projects, Objective C is a simpler and probably better choice. But if I were asked to maintain an existing code base in some C derived OOP language, I'd be more concerned about who wrote the thing than whether it was in C++ or Objective-C.

      --
      Post may contain irony: discontinue use if experiencing mood swings, nausea or elevated blood pressure.
    88. Re:One good reason... by chgros · · Score: 1

      Well, if you can add a field at run-time then by definition you can't check its presence at compile-time.

    89. Re:One good reason... by Deorus · · Score: 1

      Compare C++ to Objective-C. You might dislike the syntax of Objective-C some, but it has clear advantages:

      For each "advantage" there's also a "disadvantage". Your problem is that you know nothing about C++ and are talking out of your ass. There are cases in which smalltalk-style OOP is superior and cases where simula-style OOP is useful, and your opinion is extremely biased due to ignorance, so let me do the Internet a favor by demonstrating how clueless you really are.

      It is a strict superset of C: C compiles as Objective-C (C++ doesn't, since structs have a different syntax, among other things)

      Here I've learned that you don't even know C++. C++'s structs are exactly like C's structs, and you'd be challenged to find C11 code that doesn't compile as C++11 unless it's doing something very C specific such as to use compound literals (C++ supports initializer lists, which are neater), not casting to void * / char * (which are not universal pointer types in C++), or using keywords that are reserved in C++ such as new, delete, try, catch, operator, template, class, etc. Some of these problems also exist when you port code to Objective-C. For example, you can't use nil as a variable name.

      More importantly, it is runtime-resolved. That means you can expand Objective-C classes without breaking the ABI;

      That also means a lot of errors that a static analyzer would immediately point out in compile time are only reported as runtime errors if you are lucky enough to trigger the required conditions, thus making your code more error prone.

      in C++ you can't add members to classes, at all.

      The only place where this concern makes sense is while loading dynamic libraries, in which case you should actually only be using C or extern "C" in C++, because that's the only way you can guarantee that other languages can easily locate your symbols and don't have to deal with bindings.

      Class members can be in different libraries, and in different header files (a "private" member is one not exposed in the API, but you COULD access it directly by defining it or including the header for it).

      What?

      The mangling in C++ is a serious pain and makes loading C++ libraries and programs retardedly slow.

      Type mangling shouldn't be a problem at all unless you're trying to do something that you really should't, such as to dynamically load C++ symbols into another language. C++ gives you extern "C" precisely for the cases when you need ompatibility with the lowest common denominator (C). Also, type mangling does not slow anything down, I don't know where you got that idea from. Type mangled symbols aren't any slower or faster to load than any other symbols on any implementation that I'm aware of.

      Operator overloading and templates are an abomination, and don't exist in Objective-C.

      So Objective-C is better because it doesn't support a feature? Do you even understand generic programming at all?

      We can all supply better languages for a purpose; Objective-C and C++ have the same purpose (an object oriented general purpose native compiled mid-level programming language), and so this comparison is relevant.

      It would, if you actually had a clue of what you're talking about. The paradigms are quite different: Objective-C is dynamic, C++ is static.

      Swizzling (you can replace members of classes at runtime--not just inherit, but actually overload class members) makes the language quite a bit more flexible.

      Even C supports function pointers, and C++ adds lambdas / closures. You've been able to replace stuff at runtime all along, except in C++ you actually get to define exactly when it is OK for the users of your classes to do it.

    90. Re:One good reason... by Deorus · · Score: 1

      And presumably "*" is overloaded? And how do you know whether a pointer is smart or not? Presumably you look at the #includes? Right. What if someone uses a different smart pointer library/template/whatever?

      You declared the pointer yourself as unique_ptr<T> somewhere within the function. If you can't keep track of that, better start refactoring. Operators don't magically overload themselves.

      And what about new and delete and arrays, vectors, and all that jazz?

      New and delete are overloaded on a per-class basis, or in some cases globally for debugging purposes alone. Container classes use allocator<T> for their value types, not new / delete overloads.

      So why don't they just make pointers behave like that in the first place? Oh, because that would break backwards compatibility with C source (you are meant to have swallowed the pill and be compiling all your C code in your C++ compiler, and modify it where its broken)... even although the language isn't a strict superset of C and you can't rely on the behaviour of the compiled code to be the same...

      Because it wouldn't make sense, as those features are not used on a language-wide basis.

      There are two types of people in this world: those that pretend to understand C++ and those that don't pretend that they don't.

      And you belong to the former group.

      Next idiot question? Don't be shy now, your ignorance is already public knowledge!

    91. Re:One good reason... by GrahamCox · · Score: 1

      1. it's design
      2. it's implementation


      Syntax error in line 1: unexpected character (grocer's apostrophe error)
      Syntax error in line 2: unexpected character (grocer's apostrophe error)

      Pasring aborted: too many errors.

    92. Re:One good reason... by jc42 · · Score: 2

      C++ virtual method call 1.1 ns
      Objective C message send 4.9 ns

      4.9/1.1 ~ 4.5 times slower.

      I don't know where you're getting 10 times slower from.

      It's called an "order of magnitude" estimate. 4.5 differs from 10 by less than a factor or 10, so they're the same number.

      It's a very popular method of estimation among people who don't care for precision. You should try it sometime; it's fun. You can get geeky types who know the numbers really upset with you, while management types are giving you approving smiles. But you do seem to have "cherry picking" down pat, so you're well on your way to a career in media/political/management abuse of statistics. You just need a few more deceptive techniques in your portfolio. If you ask nice, there are lots of people here who can help you.

      --
      Those who do study history are doomed to stand helplessly by while everyone else repeats it.
    93. Re:One good reason... by Anonymous Coward · · Score: 0

      I bounce any code review I see using them.

      And I wouldn't even give you a job. Explain what 'constructors to make quasi-first order functions' actually means. And why having a canonical implementation of a sort function is a bad thing. I mean, even C has qsort. What's wrong with that?

      Value templates: It's an extremely niche use case

      Rubbish. Specialising on values is a perfectly valid use case. And anyway, even if you did remove it people would probably start writing types like 'struct one {}; struct two{};' etc.

      Lastly, your C-with-classes (have I heard that somewhere before...?) will never be used by anyone except yourself. Simply stop using the features you don't like and quit complaining.

    94. Re:One good reason... by Deorus · · Score: 2

      It always infuriated me that most C++ compilers will happily accept printf() as valid.

      Most of C's standard library is part of C++'s specification. That function in particular is defined in <cstdio>, so compilers accepting it are conforming to the standard. This is not to mention that there are actually certain manipulators that stdio accepts and iostream does not, such as the precision manipulator for character strings which limits the amount of data read from character string buffers (C99). Also don't even get me started about the real bloat that iostream actually is. If you've never implemented a custom streambuf, please by all means do it and see for yourself.

    95. Re:One good reason... by Anonymous Coward · · Score: 0

      Unless you are dealing with many similar objects in your code, such as multiple rows of a database, or multiple windows, there is no reason to use object oriented code.

      As an embedded system developer, I have little cause to use an object oriented coding language; but object oriented architecture and design is very helpful.

      C is clunky, and not as productive as C#, Tcl, or Perl for many jobs; but it beats the pluses off of C++ for ordinary embedded programming.

    96. Re:One good reason... by Deorus · · Score: 1

      Exceptions -- I personally like exceptions, but exceptions in C++ are terrible and not necessary.

      Exceptions are an essential part in any object oriented programming language. They are the only way to signal that an interaction has left an object in an invalid state.

      No clearly defined exception type -- you could potentially catch something that has no descriptive string, no information about the stack, etc.

      It's native code. If you want to see the stack, either attach a program to a running process or read the core dump. The standard defines several exception types in and , all inheriting publicly from std::exception, but it doesn't force you to use them, you're free to create your own if you wish, or to throw something else that you find relevant.

      Double exception faults. This is a subtle problem but one that seems to be easier to trigger in C++ than other languages, and one that could be fixed by changing how exceptions are handled. For those who are not familiar, exceptions that propagate out of a destructor cause abort() to be called if the destructor was called as part of the stack unwinding process for another exception. If I wanted to call abort() when errors occurred, I would not bother with throw statements, I would just call abort().

      As per my definition above, you are not supposed to be throwing exceptions in destructors, because a destructor is not supposed to be causing your object to enter an invalid state. It's already destroying itself, after all. If you're having problems with exceptions at destruction time, then your code is improperly designed.

      Incidentally, the problem here is the order in which things happen. Exceptions should be caught before the stack unwinding process, which guarantees that the handler will execute before another exception is called. This also allows for "restarts" i.e. the ability to resume execution from the point where an exception was thrown, which might make sense (e.g. for exceptions that indicate some non-critical function could not be performed, which should not prevent a critical function from completing).

      No, it does not make sense. If a destructor signals an error condition, then the object is in an invalid state, and if the object is in an invalid state then it should self-destroy, but since the error was found during destruction it can't self destroy, so the entire program is in an invalid state, and the only way out of that is to abort and let the operating system / debugger handle the mess.

      I have also seen quite a few large C++ projects that simply ban exceptions, because they wind up creating more problems than they solve.

      Indeed, which actually contradicts your earlier remark that exceptions are unnecessary.

    97. Re:One good reason... by luis_a_espinal · · Score: 1
      I was with you in the overcomplication of C++ until you hit this:

      *Kill either structs or classes. We don 't need both, with one being syntactic sugar to change the default visibility on the other

      You need structs for POD compatibility. Moreover, they are good for implementing things that are not classes, but plain old data shuttles. This has been a gripe of mine when I was in the Java world (12 years in total.) Not everything is an object, at least a conceptual object (thing DTOs). But the language does not allow you to do reflect that at all. There are a lot of things I don't like when I work with C++, but structs are not among them.

      IMO, C++ would have been much better if method/function arguments were const-ref by default (considering this is the direction new languages follow and with good reason.) But I can understand why it is not so. In many ways, C++ was ahead of its time in terms of what was available in compilers know-how.

      And the people who complain about C++'s bloat generally like Python or Ruby, which are both just as bloated as C++, without the bonus of it's simplicity.

      I disagree with you here as well. C++ is not an example of simplicity. Take all the rules a person needs to learn the first time to avoid redundant constructor calls.

      Ruby and Python are simpler (not simple, but simpler than C++). For simplicity, C. Very little hidden semantics.

    98. Re:One good reason... by Anonymous Coward · · Score: 0

      >> Templates are what makes C++ std::sort faster than C qsort.

      Inlining and not having to chase down function pointers is what makes std::sort faster. This is -because- of templates, but templates are only the facilitator.

    99. Re:One good reason... by russotto · · Score: 0

      When it comes to STL algorithms, you may have been right before C++11/C++0x. Now, with lambda functions, the standard algorithms are genuinely brilliant. Modern IDEs should support debugging the lambdas as well.

      If I wanted to use LISP, I would have used LISP. Not some bastardized lambda extension glommed onto an overgrown object-oriented extension to a procedural language.

    100. Re:One good reason... by luis_a_espinal · · Score: 1

      It's not the bloated obscenity that is C++.

      C++ is not a bloated obscenity. It is an excellent language.

      I am not claiming it is a language without warts, but I challenge any one who modded the parent post up to provide a coherent argument as to why C++ is bloated and what features you could therefore remove without detracting from the effectiveness of the language.

      1. The need for making constructors explicit for one. There shouldn't be any automatic conversions.

      2. The need to have private method declarations in the hpp.

      I understand the reasoning behind #2 (compiler limitations of the time.) It is still very painful when you have to refactor common code out of existing methods, yet that common code is an implementation detail of no use to the class' user. If the refactored common code operates only on parameters, then it can sit as a function static to the cpp. But if the refactored common code acts on the class state, then you have to make it a method, a private method. But to do that, then you have to change the interface, the hpp, the thing you supply to your class' users. A pimpl might ameliorate things, but not completely. Using ABCs might ameliorate things as well... but only some of the time.

      An implementation detail change of that tpe should not cause a change in the class interface. But in C++, it does. The insistence in having to declare your private functions (implementation details), virtual or otherwise, in the header does put a hiccup in the evolution and maintainability of a class. It is not an unresolved problem, but it can be a PITA nonetheless.

    101. Re:One good reason... by Deorus · · Score: 1

      How do you get multiple dispatch in C++?

      C++ is a static language, but you can still accomplish what you wish by defining functions for the derive types, using RTTI to perform the type comparison, and dynamic_cast to the the derived types. If you meant something else, be precise.

      Why do you have to manage the allocation and deallocation of the lexical environment when you create a closure in C++11?

      You do?

      [&](){}

      That's a pure lambda, no allocation or deallocation of anything whatsoever. If you meant something else, be precise.

      Why can exceptions cause programs to abort in C++?

      Because exceptions are supposed to signal error conditions in which an object finds itself in an invalid state, and if they aren't handled it means the exception wasn't expected thus the entire program is in an invalid state.

      Why can a C++ function claim to return something, but never actually have a return statement (which can cause things to become completely unpredictable in the case where you were supposed to return an object value where the destructor is virtual)?

      It can't as far as the standard is concerned, but most compilers allow it, assume a default value, and only display a warning. Using your compiler properly should fix the problem.

      None of these things are problems in Common Lisp.

      You didn't mention any actual problems except for the last one which is not a feature of the language.

    102. Re:One good reason... by Anonymous Coward · · Score: 0

      Except 99% of your code isn't adding a field at run-time.

    103. Re:One good reason... by Anonymous Coward · · Score: 0

      If your destructors throw exceptions, you're doing it wrong.

    104. Re:One good reason... by Pseudonym · · Score: 1

      *Diamond inheritance (just make it illegal)

      Is it a big problem? I think I had a design once where it made sense, but I can't for the life of me remember even what the domain was.

      The last time I used it was to implement a bridge pattern.

      In case you've paged it out, a bridge pattern is useful for situations when you have two incompatible inheritance hierarchies, and you need to implement one in terms of the other. The classic real world example is Java AWT, which specifies its own hierarchy of GUI widgets, but they need to be implemented in terms of a native, almost certainly incompatible, inheritance hierarchy.

      Best practice for implementing the back end of the bridge is to inherit from abstract base classes (interfaces in Java) which reflect the structure of the front end and concrete classes which reflect the structure of the back end. For anything moderately complex, you inevitably end up with the ABCs multiply inherited in diamond patterns.

      C++ has a fairly decent work-around here, namely, to inherit the base classes virtually. Even better would be if the inheritance hierarchies produced by GUI API designers weren't so unnecessarily complex to begin with, but that's another story.

      This is admittedly a highly specialist usage. Nonetheless, I wouldn't want to lose the ability to do this. You could mandate that classes at the top of a diamond must be ABCs or virtually inherited. That would solve the semantic problem, but C programmers would just complain that the standard was even more complex than it used to be.

      *The iostream libraries. I don't think I've ever seen code that didn't say fuck that and just use C style stdio.

      Oddly enough, I've lost count of the number of C programs which either rolled their own or use a third-party stdio replacement like SFIO.

      With stdio, moderately easy stuff is easy, and anything harder is impossible. With iostreams, moderately easy stuff is moderately easy, moderately east stuff is moderately difficult, and truly difficult stuff is possible.

      Well, I like the type safety of the C++ library.

      I like the abstraction layer. You try transparently decompressing a gzipped file with stdio some time!

      The formatting stinks and is really painful to use.

      That it does. And don't get me started on the "support" for i18n.

      --
      sub f{($f)=@_;print"$f(q{$f});";}f(q{sub f{($f)=@_;print"$f(q{$f});";}f});
    105. Re:One good reason... by Pseudonym · · Score: 1

      If by "algorithms" you mean "functors", I completely agree with you. If you actually meant "algorithms", then I don't understand what you're talking about.

      --
      sub f{($f)=@_;print"$f(q{$f});";}f(q{sub f{($f)=@_;print"$f(q{$f});";}f});
    106. Re:One good reason... by Pseudonym · · Score: 1

      The problem isn't writing the for_each, it's writing "bar". Even most seasoned C++ users will readily admit that for_each was pretty useless before lambdas. I'm definitely going to be using it in the future, once compiler support has been rolled out sufficiently widely.

      --
      sub f{($f)=@_;print"$f(q{$f});";}f(q{sub f{($f)=@_;print"$f(q{$f});";}f});
    107. Re:One good reason... by Pseudonym · · Score: 1

      While I agree that the standard library is mostly useless (for instance C++11 specifically supports threads but none of the standard containers supports the volatile qualifier (I'm sure someone will comment on this too, and I'll have to demonstrate, again, why volatile is still required for multithreaded development)), some of your points result from a lack of understanding of the language.

      You know the rule of the Internet that says that every spelling flame must contain a spelling mistake? Well, you don't seem to understand what "volatile" means.

      --
      sub f{($f)=@_;print"$f(q{$f});";}f(q{sub f{($f)=@_;print"$f(q{$f});";}f});
    108. Re:One good reason... by Anonymous Coward · · Score: 0

      +5 Knows What He's On About

    109. Re:One good reason... by 91degrees · · Score: 1

      What I meant to say was "pointers on the stack that point to objects dynamically allocated in freestore (on the heap)."

      Destructors aren't called when a pointer goes out of scope. Only the object.

      But pointer issues are a problem with all the C family, and pretty much any language where the user has to deal with memory management themselves. Not really related to RAII or exceptions though.

      Oh, and another thing, I once read some punditry that freestore and the heap are different in the context of C++.

      new and delete have their own memory handling routines, and call their memory area the freestore. new allocates from the freestore. malloc() allocates from the heap. They may be the same, or may not. Using delete on memory allocated by by malloc() or free() on memory allocated by new will result in unpredictable behaviour.

    110. Re:One good reason... by Anonymous Coward · · Score: 0

      No clearly defined exception type

      While use at it is not enforced the standard library contains an exception type you can and should use as base class, this normally goes unnoticed since nobody uses the throwing std::vector::at() or the iostream exceptions which inherit from std::exception.

      The only reason I can think of why inheriting from std::exception is not mandatory is the anti inheritance crowd. (pre c++11 very few things in c++ required inheritance), not using it however is beyoind stupid and any programmer throwing int should be required to rewrite the code.

      Exceptions should be caught before the stack unwinding process

      Your use case is different, exceptions are there to be used when you don't have the information to handle them severall stackframes away, the alternative in this situation is returning an error code and checking it in each calling function and its calling function and its calling function and ...... until you are have enough information to deal with the error. For your use case you can define an error handler callback and call that which is simple enough and does not overlap in any way with the purpose of c++ exceptions - ofcourse that requires your library to actually be designed to support restart.

      Double exception faults

      Other languages simply forget about the first exception which only barely works without causing anly trouble and just asks for memory leaks and undefined state in c++ (who will destruct the first exception if it was thrown as a pointer(bad but valid design)?).

    111. Re:One good reason... by dolmen.fr · · Score: 1

      This is exactly the case where smartness of those pointers shines.

    112. Re:One good reason... by TheRaven64 · · Score: 1

      Wow, I didn't realise Apple's implementation was so bad. With the GNUstep Objective-C runtime (which I maintain, so some bias here...), I ran some benchmark tests for FOSDEM on ARM Cortex A8, which is our worst-performing platform for this kind of comparison because function calls are so cheap. The cost of a message send was about 1.8 times the cost of a direct call to the function pointer. The compiler can now do automatic caching of the lookups in loops (Apple's can't), and this brings it down to about 1.6 times the cost of a direct call. C++ virtual functions are within the same ballpark.

      Note that this doesn't tell the whole story. Because Objective-C does not do the compile-time expansion that C++ does, it generates much smaller code (often 1-2 orders of magnitude) and so gives significantly better instruction cache usage. And, of course, everything within a method runs at exactly the same speed as C.

      --
      I am TheRaven on Soylent News
    113. Re:One good reason... by tyrione · · Score: 1

      It's almost half an order of magnitude slower and by saying so you come off being far more accurate without getting down into the weeds of accuracy and precision.

    114. Re:One good reason... by Deorus · · Score: 1

      You know the rule of the Internet that says that every spelling flame must contain a spelling mistake? Well, you don't seem to understand what "volatile" means.

      You're not the first misconceived person that I've had to refute about this. Volatile forces every read and write from and to memory to actually be a read and write, which among other things disables certain compiler optimizations that would incorrectly assume that a variable can not be written by anyone else.

      In the following example:

      sig_atomic_t i; void foo(void) {i = 3; while (i) i ^= 1;}

      nothing other than volatile can prevent the compiler from optimizing to:

      sig_atomic_t i; void foo(void) {for (;;);}

      with the logic behind the above optimization being that the function never actually returns as the condition in the loop is always true, and since it never returns it's not worth changing the global variable either because, really, no other function within the same execution context is going to read it again anyway. This is all fine and dandy when there's only one execution context, but fails miserably in the presence of concurrent memory access from external hardware, signal handlers, longjmp(), or threads because the changes that were supposed to happen are never made visible in memory, and it is to address those visibility problems that the volatile qualifier exists.

      Don't worry, you're not the first idiot I've refuted on the Internet about this, but I am not certain of exactly where the misconception that volatile is useless for threads started. It is true that many people think of volatile as having memory ordering enforcement properties (though I suspect this has to do with x86 enforcing acquire and release semantics on loads and stores, and some compilers actually implying fence semantics in the presence of volatiles) and that is an incorrect assumption, however to ignore the visibility problems caused by a lack of volatile usage is just as bad if not worse.

    115. Re:One good reason... by PiMuNu · · Score: 1

      default constructor, default destructor, default assignment, implicit calling of constructors... it's a mess. Half of developers don't even know that this is happening. Style guides suggest disabling this stuff.

      It's impossible to assign anything - how do you assign data to a std::vector? You need to make an array! Ack! Fixed in whatever C++011 but then they introduced a whole load more implicit type assignment problems. Ack!

    116. Re:One good reason... by betterunixthanunix · · Score: 1

      C++ is a static language, but you can still accomplish what you wish by defining functions for the derive types, using RTTI to perform the type comparison, and dynamic_cast to the the derived types. If you meant something else, be precise.

      That is as bad as doing OOP in C -- sure, you can implement OOP constructs, but it adds complexity and it adds new ways for things to crash. C++ only supports single dispatch; you are on your own if you want something more.

      That's a pure lambda, no allocation or deallocation of anything whatsoever. If you meant something else, be precise.

      I was precise: the allocation and deallocation of the lexical environment for a closure. If you return a lambda from a function and your capture specification is simply [&]. then any reference to local variables from the enclosing function in the lambda expression will be invalid. You have to capture by value i.e. with the capture specification [=], which makes a copy, but now you must ensure that you do not free your pointers until you are done using the closure.

      Because exceptions are supposed to signal error conditions in which an object finds itself in an invalid state, and if they aren't handled it means the exception wasn't expected thus the entire program is in an invalid state.

      Except that you could have a top level catch(...) block, and still wind up have your program abort when an exception is thrown. That happens if an exception propagates out of a destructor that was called as part of the stack unwinding process for another exception. This is not a problem in Lisp, since the exception handler is found before the stack unwinding process begins, which allows the stack unwinding to be optional -- a program could resume execution from the site where an exception is thrown (e.g. if you have a non-critical logging function, you probably do not want it to prevent a critical function from running).

      The C++ answer is to simply never allow exceptions to propagate out of destructors. If a destructor cannot finish for some reason, you need another way to indicate that.

      It can't as far as the standard is concerned

      No, reaching the end of a non-void function is not forbidden by the standard, it is left up to implementors to decide what to do. Some compilers will not allow it, some will warn, and some will just ignore it and compile your program without complaint.

      You didn't mention any actual problems except for the last one which is not a feature of the language.

      No, I was just not clear enough about the problems for you to understand what I meant; now that I have clarified, we can try this again.

      --
      Palm trees and 8
    117. Re:One good reason... by Anonymous Coward · · Score: 0

      Wow, I didn't realise Apple's implementation was so bad.

      Keep in mind that those are leopard benchmarks.

    118. Re:One good reason... by betterunixthanunix · · Score: 1

      Exceptions are an essential part in any object oriented programming language. They are the only way to signal that an interaction has left an object in an invalid state.

      Or you could return an error code from member functions, and test that -- which is what the iostream classes in C++ did before exceptions were added to the standard.

      It's native code. If you want to see the stack, either attach a program to a running process or read the core dump

      Except that once an exception is caught, the core dump will have no information about the stack at the point where the exception was thrown, since the stack is unwound by that point. If you want core dumps that include that information, you basically need to replace throw with abort(), or you need a function that causes the core to be dumped without killing the process (perhaps you can point to one).

      Also, exceptions in native code can have information about the stack -- if the stack is not unwound before the exception is caught. If you wanted a core dump with that stack included, you could call abort at that point; you could also resume execution from where the exception was thrown e.g. if you do not want to halt a critical function because of a non-critical error.

      If a destructor signals an error condition, then the object is in an invalid state

      Not true; the exception may have nothing to with the object being destroyed. Suppose, for example, that you have a class that encapsulates your logging process, and the destructor for that class closes the log file. Suppose some function creates a local object of that type, and then tries to write to a separate output file; the write may fail because you ran out of disk space, and that should cause an exception to be thrown. However, if that exception is not caught in the function that created the logging object, then the attempt to close the log file might also fail -- since it might try to flush the stream, which will fail because there is no disk space left. That too should cause an exception to be thrown, but that is not a result of the logging object being in an invalid state (there is nothing that the class could do to prevent the error).

      It is not always the case that you want to abort execution in that case; at the very least, you might want to send a message about running out disk space before exiting, or perhaps continue executing but stop writing to disk.

      so the entire program is in an invalid state

      No, the program is in an error state, which may first require the program to enter additional error states before execution can be resumed. Calling abort() is supposed to be an absolute last resort, reserved for situations where the program has no way to continue executing correctly. Exceptions are supposed to prevent programs from entering invalid states by forcing programs to enter error states; that is why exceptions as an idea are generally good. The problem is that in C++ (and to be fair, several other languages), the transition to the error state can trigger additional errors, which makes the correct error state ambiguous.

      Which is why, again, the correct way to do this is for the exception handler to be located before the stack is unwound. That guarantees that the transition to the error state is completed before anything else happens, which leaves no ambiguity in which error state is entered. It also allows you to return to the next instruction following the throw, which is probably what you want if the exception is of low priority (e.g. maybe you just issue a warning to the user and give them the choice to continue or not).

      --
      Palm trees and 8
    119. Re:One good reason... by Deorus · · Score: 1

      That is as bad as doing OOP in C -- sure, you can implement OOP constructs, but it adds complexity and it adds new ways for things to crash. C++ only supports single dispatch; you are on your own if you want something more.

      No, actually it's impossible to implement OOP in C. OOP requires self-awareness (i.e.: a this pointer), and C does't have that, so you can't implement instance member functions at all. RTTI, however, is fully supported by C++; you need to put some effort to use it, but the building blocks are fully supported by the language, and you will get the appropriate runtime errors if you dynamic_cast into the wrong type. If it wasn't this way, you'd lose the static analysis and thus end up with code that is more error prone because mistakes that could have easily been spotted at compile-time are left for you to bump against at runtime, and this, to me, is a lot more important than the edge cases in which I can not rely on virtual functions and may need to downcast.

      I was precise: the allocation and deallocation of the lexical environment for a closure. If you return a lambda from a function and your capture specification is simply [&]. then any reference to local variables from the enclosing function in the lambda expression will be invalid. You have to capture by value i.e. with the capture specification [=], which makes a copy, but now you must ensure that you do not free your pointers until you are done using the closure.

      Yes, I actually meant [=] when I posted that. That's the main theoretical difference between closures and lambdas: lambdas capture by value whereas closures capture by reference. Regarding your pointer issue, the language specifies smart pointers, and you can even implement your own, so I don't see an issue there. As a matter of fact you should actually be using at least unique_ptr to make sure that RAII takes proper care of the destruction of dynamic objects when an exception is thrown.

      Except that you could have a top level catch(...) block, and still wind up have your program abort when an exception is thrown. That happens if an exception propagates out of a destructor that was called as part of the stack unwinding process for another exception. This is not a problem in Lisp, since the exception handler is found before the stack unwinding process begins, which allows the stack unwinding to be optional -- a program could resume execution from the site where an exception is thrown (e.g. if you have a non-critical logging function, you probably do not want it to prevent a critical function from running).

      I have already addressed that "issue" elsewhere in this thread. Destructors should not throw exceptions. Exceptions are meant to signal error conditions in which an action performed on an object causes it to enter an invalid state, and destroying an object should never cause that because, well, the object is being destroyed... If the object self-destroys by throwing an exception and then a destructor throws another exception, then the entire program is in an invalid state because the object is supposed to have been destroyed when the second exception was thrown, and now you are left with absolutely no means to destroy that objects, nor can you, as a user, tell exactly how destroyed it was before it threw that exception. Destructors in C++11 are noexcept precisely because handling a destructor exception is as pointless as handling a SIGSEGV (though the latter can still be useful when you are implementing user land threads / fibers).

      No, reaching the end of a non-void function is not forbidden by the standard, it is left up to implementors to decide what to do. Some compilers will not allow it, some will warn, and some will just ignore it and compile your program without complaint.

      Wrong, the final publication of ISO/IEC-14882 Third Edition 2011-09-01 states, in 6.6.3p2, that "Flowing off

    120. Re:One good reason... by Deorus · · Score: 1

      Or you could return an error code from member functions, and test that -- which is what the iostream classes in C++ did before exceptions were added to the standard.

      If the user asks for the result of an action, they are expecting the result of that action, not an error. The problem with in-band error checking is that, on top of requiring lots of repetitive code, including cleanup code (or alternatively, heavy goto usage), it also prevents you from chaining calls because in-band error values don't interrupt the flow of code, and if the fact that you can not do foo().bar().baz() anymore with error checking wasn't bad enough, the inability to chain calls also makes generic programming impossible (i.e.: you can't feasibly do 1 + 2 + 3 + 4 + 5 or even a + b + c either).

      Not true; the exception may have nothing to with the object being destroyed. Suppose, for example, that you have a class that encapsulates your logging process, and the destructor for that class closes the log file. Suppose some function creates a local object of that type, and then tries to write to a separate output file; the write may fail because you ran out of disk space, and that should cause an exception to be thrown. However, if that exception is not caught in the function that created the logging object, then the attempt to close the log file might also fail -- since it might try to flush the stream, which will fail because there is no disk space left. That too should cause an exception to be thrown, but that is not a result of the logging object being in an invalid state (there is nothing that the class could do to prevent the error).

      OOP is a synchronous paradigm; and the case that you are describing is asynchronous. If closing the file fails, it's up to you to try again until it succeeds. If you can't handle that problem, then how are you expecting the user of your class to handle it? If you can't ensure proper destruction, then the entire program is left in an invalid state since from that point forward it is no longer possible to determine how to recover from a partial destruction.

      Also, exceptions in native code can have information about the stack -- if the stack is not unwound before the exception is caught. If you wanted a core dump with that stack included, you could call abort at that point; you could also resume execution from where the exception was thrown e.g. if you do not want to halt a critical function because of a non-critical error.

      If you don't catch the exception, it will abort and dump core and you will be able to examine the stack with that. If you catch the exception, then you are pretty much telling the implementation that you don't really care about debugging because the error is expected and you can take care of it at runtime. You should not be catching exceptions unless you have pretty good reasons to do so and know exactly what you want to handle. For example: while a write error for lack of space exception should be handled and displayed to the user (as this error results from conditions unrelated to your program), a write error due to your use of an invalid file descriptor should not (because this error signals a potential bug in your code).

      No, the program is in an error state, which may first require the program to enter additional error states before execution can be resumed. Calling abort() is supposed to be an absolute last resort, reserved for situations where the program has no way to continue executing correctly. Exceptions are supposed to prevent programs from entering invalid states by forcing programs to enter error states; that is why exceptions as an idea are generally good. The problem is that in C++ (and to be fair, several other languages), the transition to the error state can trigger additional errors, which makes the correct error state ambiguous.

      Exceptions cause objects to self-destroy. If the destructor

    121. Re:One good reason... by DemonGenius · · Score: 1

      As a general rule, I never use aspects of a programming language that I think are broken, antiquated or unfamiliar unless I become familiar with its use and I know exactly what I'm getting myself into with its usage. I say keep whatever features that already exist in a language for those that know how to use them. Don't fault the language for what some developers are incapable of doing right.

      Programming languages are like tools, but too often we see people who feel the need to hammer in a screw.

    122. Re:One good reason... by Bengie · · Score: 1

      Just be careful with "Volatile", as many new CPUs may re-arrange memory access, which can break a lock-less algorithm that assumes Volatile fixes everything.

    123. Re:One good reason... by betterunixthanunix · · Score: 1

      OOP requires self-awareness (i.e.: a this pointer), and C does't have that

      So you manually pass that to all member functions, like you would in Objective C or CLOS. You pretty much do that in C++, it just looks prettier:

      Classname obj;
      obj.member(arg);

      In C, that just looks a bit uglier:

      struct Classname obj;
      Classname_constructor(&obj);
      Classname_member(&obj, arg);

      You can manually implement a vtbl for single dispatch, or even a more complicated structure for multiple dispatch, if you want. Yet nobody would claim that C has OOP facilities, just like nobody should claim that C++ does not lack multiple dispatch.

      thus end up with code that is more error prone because mistakes that could have easily been spotted at compile-time

      ...oh the irony...

      int * x = 0;
      x[0] = 5;

      the language specifies smart pointers

      They are not required, even for closures. The use of a smart pointer in C++ is just a "nice" way to manage allocation and deallocation; it is not something that the language itself provides, it is provided by a library. That is basically working around the fundamental problem, which is that the environment of a closure and the closure itself are allocated, managed, and deallocated separately. The fact that you can destroy the environment of the closure but continue to use the closure is the problem here. It is like calling an object's destructor, but continuing to use the object after that.

      As a matter of fact you should actually be using at least unique_ptr to make sure that RAII takes proper care of the destruction of dynamic objects when an exception is thrown.

      Why, then, is that not a requirement? Why not require, at the very least, that all pointers to objects be smart pointers? Or perhaps just objects that are captured by a closure? I do not understand this philosophy of, "Well it is your fault for failing to adhere to best practices!" while simultaneously designing a language where the best practices are complicated (whole books have been published about how not to screw up C++ programs) and easy to ignore.

      Destructors should not throw exceptions

      Yet nothing stops that from happening. There is no requirement that destructors have a catch(...) block, nor is there a requirement that destructors have an empty exception specification (or that any exception specifications exist anywhere).

      Exceptions are meant to signal error conditions in which an action performed on an object causes it to enter an invalid state, and destroying an object should never cause that because, well, the object is being destroyed

      As I said elsewhere (maybe the same thread? sorry if we are arguing in two places at the same time), that is not true. An exception could be thrown as a result of a file being closed, and there are numerous other cases where routine things that happen in destructors can throw exceptions for things that cannot be controlled by any member function. Not all exceptions are fatal, and that includes exceptions that are thrown within a destructor.

      Destructors in C++11 are noexcept precisely because handling a destructor exception is as pointless as handling a SIGSEGV

      No, it is because exceptions in C++ are implemented the wrong way. The stack should not be unwound until the exception handler is located, period. Unwinding the stack first is what creates this messy situation with exceptions that propagate out of destructors. The C++ standards committee spent too much time listening to compiler authors when it came to this issue; unwinding the stack first is easier to implement efficiently (unwinding after

      --
      Palm trees and 8
    124. Re:One good reason... by bluefoxlucid · · Score: 1

      Haruchai.. annoying telepathic mountain-folk.

    125. Re:One good reason... by Anonymous Coward · · Score: 0

      Maybe you should forget about non-deterministic options in C++? I mean you're doing *realtime* stuff,

    126. Re:One good reason... by betterunixthanunix · · Score: 1

      If the user asks for the result of an action, they are expecting the result of that action, not an error.

      Except that there might be an error, which is the point of exceptions. I agree in principle that exceptions are a good thing -- I just think the C++ implementation is bad, mainly because there is no way to know if any exception will actually be caught even if you have a catch(...). The double exception fault basically reduces exceptions to Unix signals -- you should never rely on exceptions for cleanup, nor should you even rely on the program continuing to execute at all after an exception is thrown.

      OOP is a synchronous paradigm; and the case that you are describing is asynchronous

      How is that? For simplicity, you can just assume that your program is the only program in the entire system -- imagine that we are back in the days of DOS. That does not mean that you will never have an uncommitted write; you might be using buffered I/O, and the buffer will need to be flushed when the file is closed.

      If closing the file fails, it's up to you to try again until it succeeds

      Which basically means that you need to have try blocks with a single function, in a loop, and that the catch blocks are responsible for breaking out of the loop. You might as well revert back to using return values if you do that.

      If you can't handle that problem, then how are you expecting the user of your class to handle it?

      By giving the user a chance to skip over the error, if that is what they want to do. Again, in some programs, it will be better to just ignore that error, but in others it will not be -- and it may even depend on which part of the program you are in. Maybe I am willing to ignore exceptions thrown when i try to close a file, but only when I am already in a catch block for some other exception.

      For example: while a write error for lack of space exception should be handled and displayed to the user (as this error results from conditions unrelated to your program), a write error due to your use of an invalid file descriptor should not (because this error signals a potential bug in your code).

      I agree, some errors are more serious than others; but if the write error is a result of lack of disk space, that program should not abort because a file could not be closed as a result of lack of disk space.

      How can you finish the destruction of that object now that it is partially destructing while ensuring that its destructor (which was clearly not designed for this) won't tap into undefined behavior will correctly destroy the partially destroyed object?

      By resuming execution from a restart point defined by the exception itself. This is where having a well defined exception class hierarchy is necessary: you can have a "RestartableException" type, which should only be thrown in cases where the error is not a result of a bad program state (i.e. it should not be thrown for null pointers or divisions by zero, but it should be thrown if there is an I/O error, since that is something that can potentially be corrected). So, for example, a hypothetical RestartableIOException would have a special member function that causes control flow to return to a point where the operation can be tried again -- in the case of a write, perhaps that would cause the write to be attempted again, so if the error was a full disk and some space was freed by the user, the operation can proceed. It might also make sense for some exceptions to have a "skip-to" point, which would allow a single operation to be aborted e.g. to allow a more important operation to finish before a program exits (e.g. maybe you need to explicitly roll back a transaction in a database before quitting; errors from the logging system should not stop you).

      This would also resolve the destructor issue. A call to close in a destructor sh

      --
      Palm trees and 8
    127. Re:One good reason... by haruchai · · Score: 1

      Only incestuously telepathic.

      --
      Pain is merely failure leaving the body
    128. Re:One good reason... by Deorus · · Score: 1

      Except that there might be an error, which is the point of exceptions. I agree in principle that exceptions are a good thing -- I just think the C++ implementation is bad, mainly because there is no way to know if any exception will actually be caught even if you have a catch(...). The double exception fault basically reduces exceptions to Unix signals -- you should never rely on exceptions for cleanup, nor should you even rely on the program continuing to execute at all after an exception is thrown.

      There is, don't throw exceptions from destructors! It's wrong! It's anti-pattern! It serves no purpose!

      How is that? For simplicity, you can just assume that your program is the only program in the entire system -- imagine that we are back in the days of DOS. That does not mean that you will never have an uncommitted write; you might be using buffered I/O, and the buffer will need to be flushed when the file is closed.

      A destructor is a deallocator, it's not supposed to synchronize or guarantee anything else, only free resources. If the resource that your object represents is asynchronous, then you should implement a sync() function that its users can call to guarantee that nothing is lost before explicitly destroying the object.

      Since this pretty much kills your line of thought, I see no point in replying to the rest of your post.

    129. Re:One good reason... by betterunixthanunix · · Score: 1

      A destructor is a deallocator, it's not supposed to synchronize or guarantee anything else, only free resources

      And how is closing a file not freeing a resource? Here, from the implementation of fstream on my own system, is a destructor that closes a file:

      virtual ~basic_filebuf() {this->close();}

      Here, from the C++ standard itself:

      virtual ~ basic_filebuf ();

      3 Effects: Destroys an object of class basic_filebuf. Calls close().

      Yes, in case you are wondering, the C++ standard does require the close() member to flush any unwritten data and that it have the effect of closing a file:

      basic_filebuf * close ();

      Effects: If is_open() == false, returns a null pointer. If a put area exists, calls overflow(traits::eof()) to flush characters. If the last virtual member function called on *this (between underflow, overflow, seekoff, and seekpos) was overflow then calls a_codecvt .unshift (possibly several times) to determine a termination sequence, inserts those characters and calls overflow(traits::eof()) again. Finally it closes the file ("as if" by calling std::fclose(file )).323) If any of the calls to overflow or std::fclose fails then close fails.

      Since this pretty much kills your line of thought,

      Solid argument you have there -- restate your personal definition of a destructor, then declare that I must be wrong if I disagree. I am just going to guess that you have not spent much time reading the C++ standard, though, since your argument applies equally to the C++ standard itself.

      I see no point in replying to the rest of your post.

      No, you are just unable to come up with anything better than a definition of destructors that precludes double exception faults, and a definition of exceptions that precludes restarts. You might as well have stated your argument more concisely:

      I think betterunixthanunix is wrong. Therefore, I am right!

      --
      Palm trees and 8
    130. Re:One good reason... by Deorus · · Score: 1

      You can manually implement a vtbl for single dispatch, or even a more complicated structure for multiple dispatch, if you want. Yet nobody would claim that C has OOP facilities, just like nobody should claim that C++ does not lack multiple dispatch.

      The moment you start passing structs as arguments and calling functions that are declared outside of the struct that is supposed to be your object you can no longer talk about object oriented programming because there really is absolutely no relationship between the function and the object. Furthermore constructors, destructors, inheritance, polymorphism, and encapsulation are all missing features in addition to the already mentioned lack of self-awareness. The method that I described, in the other hand, can be regarded as an actual feature of the language, as it allows you to decide between calling the overload for the base class or the overload for the derived class on top of also offering you enough static analysis to inform you, at compile-time, whether the version of the overload that you wish to call is actually available without any drawbacks at all.

      They are not required, even for closures. The use of a smart pointer in C++ is just a "nice" way to manage allocation and deallocation; it is not something that the language itself provides, it is provided by a library.

      The library is part of the language, and one of the strengths of C++ is that, by not being part of the core, these features are both optional and replaceable by custom versions.

      That is basically working around the fundamental problem, which is that the environment of a closure and the closure itself are allocated, managed, and deallocated separately.

      This is not a problem: C++ supports 4 types of storage duration constraints: static, thread_local, dynamic, and auto, and smart pointers serve the purpose of binding objects with dynamic storage duration to other kinds of storage duration. There is absolutely nothing wrong wit this, choice is a good thing, and the only reason why you feel uncomfortable with this is because your functional background has limited your mind to a more restrictive set of storage duration constraints.

      The fact that you can destroy the environment of the closure but continue to use the closure is the problem here. It is like calling an object's destructor, but continuing to use the object after that.

      If you mean closure as in everything captured by reference, then you can't actually do that (it's undefined behavior); if you mean lambda as in everything captured by value, then I see absolutely no reason for you not to be able to do it since you are accessing a copy of the original environment, not the original environment itself.

      No, it is because exceptions in C++ are implemented the wrong way. The stack should not be unwound until the exception handler is located, period. Unwinding the stack first is what creates this messy situation with exceptions that propagate out of destructors. The C++ standards committee spent too much time listening to compiler authors when it came to this issue; unwinding the stack first is easier to implement efficiently (unwinding after the exception is caught can be implemented efficiently, it is just harder for the compiler writer to do).

      As I have explained in the previous post, which you pretty much ignored for whatever reasont, it makes no sense to implement exceptions any differently. Destructors are not the place to throw exceptions, if nothing else then just because static and thread_local storage durations create situations in which you can simply not catch exceptions from destructors. You are not supposed to throw exceptions from destructions, at all, it doesn't make any sense no matter how you look at it because destroying an object should never leave it in an invalid state (and if it does, the program shou

    131. Re:One good reason... by Deorus · · Score: 1

      And how is closing a file not freeing a resource?

      Closing a file is freeing a resource, that was not my point. My point is that freeing that resource should not throw an exception. If there's an error, handle it in the destructor itself because at that point it's too late to throw anything, and if you really must throw something then don't expect it to be caught, because there really is no way to catch an exception from an object with either static or thread_local storage duration even if you ignore everything else I said. If the user of the class is really interested in making sure that all the data has been flushed (or in handling exceptions if it isn't), they should call sync() before deleting; try delete is simply stupid; either it really deletes appropriately or everything is fucked up and the program must abort.

      Solid argument you have there -- restate your personal definition of a destructor, then declare that I must be wrong if I disagree. I am just going to guess that you have not spent much time reading the C++ standard, though, since your argument applies equally to the C++ standard itself.

      I don't know exactly which standard is that you're reading, but I am reading ISO/IEC-14882 Third edition 2011-09-01 AKA the final publication of the C++11 standard, not a draft or an outdated standard, and it states the following regarding the destructor for basic_filebuf:

      "Effects: Destroys an object of class basic_filebuf<charT,traits>. Calls close(). If an exception occurs during the destruction of the object, including the call to close(), the exception is caught but not rethrown (see 17.6.5.12)." [27.9.1.2p5].

      As in the previous post, I will ignore the rest of what you wrote since on top of having completely destroyed your line of thought here, I have actually demonstrated that you are to blame for the things that you are accusing me of doing.

    132. Re:One good reason... by Pseudonym · · Score: 1

      You're not the first misconceived person that I've had to refute about this.

      On the contrary, I've done a lot of multithreaded and lock-free programming, and I used to write compilers for a living. I very much know what volatile does, and I know that it's almost useless for multithreaded programming.

      I say "almost" because it effectively did the job on older architectures which enforced a total ordering on memory operations. Admittedly, it works if you only ever run your multithreaded programs on a single CPU; this does happen, especially in embedded environments. On the minus side, it's positively dangerous for any situation which assumes that loads and stores are issued and completed in the same order that you wrote them.

      Thankfully, there is a simple way to achieve what you actually want: use _Atomic (in C) or std::atomic (in C++).

      --
      sub f{($f)=@_;print"$f(q{$f});";}f(q{sub f{($f)=@_;print"$f(q{$f});";}f});
    133. Re:One good reason... by betterunixthanunix · · Score: 1

      The moment you start passing structs as arguments and calling functions that are declared outside of the struct that is supposed to be your object you can no longer talk about object oriented programming because there really is absolutely no relationship between the function and the object

      There is such a relationship: the function expects its first argument to be an instance of the struct. Object oriented programming is not limited to using languages with explicit object oriented constructs.

      Furthermore constructors, destructors, inheritance, polymorphism, and encapsulation are all missing features in addition to the already mentioned lack of self-awareness

      Wrong on all counts; all those things are possible, they are just not performed or enforced by the compiler:

      • Constructors and destructors must be called by hand as part of the process of allocating the object.
      • Inheritance can be accomplished by giving each struct a pointer to its subclass and superclass data.
      • Polymorphism can be accomplished by create an array of pointers to functions, which can be overridden.
      • Encapsulation is accomplished by only using the functions you defined to interact with the class

      The method that I described, in the other hand, can be regarded as an actual feature of the language

      No, it is just a hack using RTTI. You might as well claim that using a textbook visitor pattern means that you have double dispatch; the effect is the same, but you are using other language features to compensate for / implement a missing feature.

      The library is part of the language, and one of the strengths of C++ is that, by not being part of the core, these features are both optional and replaceable by custom versions.

      Except that you still need some set of core language features. The library can only go so far in compensating for inherent drawbacks in the design of the language.

      There is absolutely nothing wrong wit this, choice is a good thing, and the only reason why you feel uncomfortable with this is because your functional background has limited your mind to a more restrictive set of storage duration constraints.

      Actually, I have a C++ background -- most of the code I have written in my life has been C++. I just do not think that C++ is that great of a language; debugging C++ code often involves debugging the mechanics of a program, rather than the logic i.e. locating a dangling pointer, figuring out where an array bound is not being checked, etc. Programmers have spent countless hours dealing with these issues, there have been countless bugs and security vulnerabilities resulting from bad program mechanics, and most of the time the software in question did not need to be written in a low level language. Even in cases where the software does need to be written in a low level language, there is no excusing a language whose standard does not explicitly forbid statements that cannot possibly produce correct code, and there are numerous such cases in C++.

      As I have explained in the previous post, which you pretty much ignored for whatever reason

      I have not ignored anything. You have simply dismissed the idea that exceptions could be recoverable, despite having clear examples of situations where recovery is both possible and appropriate.

      Destructors are not the place to throw exceptions, if nothing else then just because static and thread_local storage durations create situations in which you can simply not catch exceptions from destructors

      Why does the language allow exceptions to propagate out of destructors at all then? Requiring destructors to be noexcept is meaningless when there is no requirement that exception specifications be declared or followed. Destructors can and do call other functions, and those functions might t

      --
      Palm trees and 8
    134. Re:One good reason... by betterunixthanunix · · Score: 1

      My point is that freeing that resource should not throw an exception

      OK, but sometimes errors occur when a resource is being freed, and there needs to dealt with somehow. What are you suggesting happen in that case?

      if you really must throw something then don't expect it to be caught

      That is true of exceptions in general, regardless of where they are thrown. That is one of the downsides of exceptions: there is no guarantee that the program will even continue to run after an exception is thrown, even if the exception is thrown from a non-destructor.

      If the user of the class is really interested in making sure that all the data has been flushed (or in handling exceptions if it isn't), they should call sync() before deleting

      Unless the object is deallocated because the stack is being unwound, in which case the only guarantee you have is that the destructor will be called.

      "Effects: Destroys an object of class basic_filebuf. Calls close(). If an exception occurs during the destruction of the object, including the call to close(), the exception is caught but not rethrown (see 17.6.5.12)." [27.9.1.2p5].

      OK, I must have been looking at something out of date; sorry about that. The point was not about the standard allowing an exception to propagate out of a destructor, however; the point was that the destructor for basic_filebuf will flush its buffer and then close the file, something you are claiming is a bad thing to do.

      That being said, if flushing or closing the file causes an error, the standard essentially says that the error should just be ignored -- no exception will be thrown, and there is not even a global error flag that can be checked. How is that a good thing? That is on the level of Java's approach to double exception faults (when exceptions propagate out of finally blocks), which is have one of the exceptions just disappear. The entire point of exceptions is that they cannot be ignored; allowing exceptions to just stop propagating or having a standard the requires errors to happen silently is a violation of the entire premise of exceptions. We might as well just stick with global error flags and checking return values if that is what we consider to be acceptable.

      Once again, the right answer is for the stack to be unwound after the exception is caught. If the user does not want to try a restart, they can at least have a chance to catch exceptions that are thrown during the unwinding process.

      I will ignore the rest of what you wrote since on top of having completely destroyed your line of thought here,

      You have done no such thing. All you have done is reiterate your view that there is never a good reason for an exception to propagate out of a destructor, changed your argument about flushing and closing files in a destructor, and promoted the idea that errors should happen silently. All that just to defend the C++ approach to exceptions -- and all that despite the fact that better approaches have already been implemented and have proved their worth in other languages.

      --
      Palm trees and 8
    135. Re:One good reason... by Deorus · · Score: 1

      OK, but sometimes errors occur when a resource is being freed, and there needs to dealt with somehow. What are you suggesting happen in that case?

      Deal with them in the destruction; abort execution with an unexpected exception if handling the error is found to be impossible, because if your class that has knowledge of its own internals and the resources that it represents can not free its resources, nobody else can.

      That is true of exceptions in general, regardless of where they are thrown. That is one of the downsides of exceptions: there is no guarantee that the program will even continue to run after an exception is thrown, even if the exception is thrown from a non-destructor.

      Except destructor exceptions aren't supposed to be caught at all.

      Unless the object is deallocated because the stack is being unwound, in which case the only guarantee you have is that the destructor will be called.

      That's the trade-off with deferred synchronization: you exchange performance for reliability. Make your class synchronous if reliability is that important to you.

      OK, I must have been looking at something out of date; sorry about that. The point was not about the standard allowing an exception to propagate out of a destructor, however; the point was that the destructor for basic_filebuf will flush its buffer and then close the file, something you are claiming is a bad thing to do.

      I never claimed that you shouldn't sync in a destructor, I claimed that you shouldn't throw exceptions if it fails, because destruction time is already too late to expect synchronization. Feel free to do all the damage control you think you should do in the destructor, just don't expose your users to its hazards! That's wrong! If I ask for an instance of your class to delete itself, I do not want to be dealing with synchronization excepts because that's not what I asked for!

      That being said, if flushing or closing the file causes an error, the standard essentially says that the error should just be ignored -- no exception will be thrown, and there is not even a global error flag that can be checked. How is that a good thing?

      Asynchronous resources sacrifice reliability for performance. If reliability is that important to you, make your interface synchronous.

      The entire point of exceptions is that they cannot be ignored; allowing exceptions to just stop propagating or having a standard the requires errors to happen silently is a violation of the entire premise of exceptions. We might as well just stick with global error flags and checking return values if that is what we consider to be acceptable.

      Wrong premise: the point of an exception is to interrupt the flow of code and signal a condition in which an object has entered an invalid state; anything beyond that is bullshit. Just because a callee signaled an invalid state doesn't mean the caller itself has entered an invalid state, especially when the caller is attempting to do something beyond its premise (such as a destructor trying to sync).

      Once again, the right answer is for the stack to be unwound after the exception is caught. If the user does not want to try a restart, they can at least have a chance to catch exceptions that are thrown during the unwinding process.

      The right answer is for you to learn OOP.

      You have done no such thing. All you have done is reiterate your view that there is never a good reason for an exception to propagate out of a destructor, changed your argument about flushing and closing files in a destructor, and promoted the idea that errors should happen silently. All that just to defend the C++ approach to exceptions -- and all that despite the fact that better approaches have already been implemented and hav

    136. Re:One good reason... by Dixie_Flatline · · Score: 1

      Templates are an abomination for two reasons:

      1) They're a solution to a problem that never should have existed. It was a ridiculous oversight to not design in type-agnostic containers.

      2) Most of the functionality of templates is discovered. It was designed to do one thing and ended up doing a lot more. The template meta-programming language is Turing complete. I hear people talk about how powerful it is, and it makes me crazy. Of course it's powerful. If you slapped any scripting language onto the the side of c++ it would be enormously powerful.

      Ultimately, this is my problem with c++ as a whole: most of the design is half-assed and sloppy. 10 or 11 years ago, I remember reading (right here on /.!) that, for the first time EVER, someone had written a parser that implemented the entire c++ specification. Before that, it was unclear whether it had a bad recursion hidden in it somewhere. Think about that. Not even the language designers could have told you if the specification was fundamentally correct.

      The best parts of c++ are the parts that are most like c. Small and efficient. I work in the games industry and engines like unreal use c++ constructs sparingly and with great care because of size and speed restraints. Most engines write their own vector types; almost nobody uses the template library. Memory managers are written so that no programmer ever actually has to alloc anything on their own. Effectively, the engine is written to protect the programmers from the language.

    137. Re:One good reason... by Deorus · · Score: 1

      No, it is just a hack using RTTI. You might as well claim that using a textbook visitor pattern means that you have double dispatch; the effect is the same, but you are using other language features to compensate for / implement a missing feature.

      Can you name a valid RTTI use that you don't consider a "hack"? Can you explain the existence of RTTI if not to solve this particular issue? And if you agree that RTTI exists to solve this particular issue, then what makes my intended use of it a "hack"?

      Except that you still need some set of core language features. The library can only go so far in compensating for inherent drawbacks in the design of the language.

      What can you not do with the library that you think is necessary and should absolutely be in the core?

      Actually, I have a C++ background -- most of the code I have written in my life has been C++. I just do not think that C++ is that great of a language; debugging C++ code often involves debugging the mechanics of a program, rather than the logic i.e. locating a dangling pointer, figuring out where an array bound is not being checked, etc. Programmers have spent countless hours dealing with these issues, there have been countless bugs and security vulnerabilities resulting from bad program mechanics, and most of the time the software in question did not need to be written in a low level language. Even in cases where the software does need to be written in a low level language, there is no excusing a language whose standard does not explicitly forbid statements that cannot possibly produce correct code, and there are numerous such cases in C++.

      I hope, for the sake of competence, that you are aware that all those examples you give can be fixed by proper debug libraries with custom smart pointers, custom array containers, custom allocators, and custom new, new[], delete, and delete[] overloads. Such libraries can raise exceptions and abort at the first sign of odd behavior like a delete leaving more than one dangling pointer, an attempt to dereference a pointer that has not been initialized or reset after its pointee got deleted with information in the exception about the exact line where the pointee was deleted, a pointer reassignment resulting in a memory leak, an out-of-bounds access to a generic sequence container, etc. C++'s staticity also allows for very powerful static analysis so that problems like the one you described earlier where a lambda capturing its environment by reference is assigned to a variable with a storage duration that is incompatible with the captured environment on top of all the stuff that is already possible to detect without extra tools thanks to C++'s strong typing and template metaprogramming. Also, thanks to being a native language, C++ can take advantage of all the available native debugging tools ranging from IDA Pro to Valgrind. Lastly, these are problems that you continue to have to deal in higher level languages, except you may not end up having security issues because of them, but if that's your problem you can always implement your own garbage collector, your own safe smart pointers, your own safe containers, and your own allocators thanks to C++'s generic programming support. You will obviously suffer a performance hit, but that's what you get in exchange for safety.

      I have not ignored anything. You have simply dismissed the idea that exceptions could be recoverable, despite having clear examples of situations where recovery is both possible and appropriate.

      Not without violating the principle of self-containment. So far in this thread everyone claiming that C++ exceptions have a problem are yet to demonstrate a single case in which catching a destructor exception would make any sense and does not imply bad design of their classes, so feel free to try...

      Why does the language allow exceptions to propagate out of d

    138. Re:One good reason... by betterunixthanunix · · Score: 1

      Deal with them in the destruction; abort execution with an unexpected exception if handling the error is found to be impossible, because if your class that has knowledge of its own internals and the resources that it represents can not free its resources, nobody else can.

      OK, but if the error can be corrected, then the destructor can proceed. Are you suggesting that the class should know both how to deallocate itself and how to correct external errors?

      Except destructor exceptions aren't supposed to be caught at all.

      Which means that there is a class of errors that the clients of the class will never have the ability to handle. Even something as simple as logging errors cannot happen under that rule.

      I never claimed that you shouldn't sync in a destructor, I claimed that you shouldn't throw exceptions if it fails, because destruction time is already too late to expect synchronization

      Then why sync at all? If it is not something that should be expected to work properly, then it is not something that should be done.

      Feel free to do all the damage control you think you should do in the destructor, just don't expose your users to its hazards! That's wrong!

      I am not seeing why that is any more wrong than throwing an exception from a constructor or a member function. We do not typically catch an exception, then say, "OK, time for this object to be destroyed, because it is in an invalid state!" If your disk is full when you call write(), and you might correct the error, then you call write again; you do not have to throw your hands in the air and destroy the object. Yet you are claiming that when it comes to destructors, things should be different -- not just that things are different, which we agree on, but that the difference is justified.

      I disagree; the difference is not justified, and the fix is not incompatible with the purpose of a destructor. The fix is to support restarts, so that an exception handler can allow control flow to return to a point defined by whatever threw the exception. If the error can be corrected, there is no reason for the destructor to not finish, but it is wrong to expect the destructor to know how to correct errors. The error might have come from some function the destructor called; why should the destructor know what to do about such errors?

      The approach you are suggesting is that if the destructor does not have any good way to deal with an error, the destructor should just fail silently. Even a global error flag is better than that.

      Asynchronous resources sacrifice reliability for performance. If reliability is that important to you, make your interface synchronous.

      That is a false dichotomy. We can have both reliability and performance, by allowing errors to be corrected. The ugly way to do that is to enclosing synchronization routines in loops, and to have catch blocks that take corrective action and then resume the loop. The not ugly way is to support restarts, so that error handling code can resume the execution of whatever code threw the exception once the exception has been corrected.

      Wrong premise: the point of an exception is to interrupt the flow of code and signal a condition in which an object has entered an invalid state; anything beyond that is bullshit.

      So off the bat, you just dismiss the idea that you could ever correct the error and continue the execution of whatever code caused the exception to be thrown. If you have an object that will write to a file, and you catch an exception that indicates the disk is full, what will you do? How will your code be anything other than an ugly mess of loops and error handling code that is scattered all over the place?

      Just because a callee signaled an invalid state doesn't mean

      --
      Palm trees and 8
    139. Re:One good reason... by Xest · · Score: 1

      The problem is that your argument seems to hinge on the fact that Objective-C is better, because it removes things that you can use incorrectly, forcing you to write better code.

      That's a fair assesment, but then you may as well argue, why even use Objective-C when Java or C# also do exactly this better than Objective-C does?

      The major selling point, the main reason you'd use C++ nowadays is because it's flexible, because it does provide you a wealth of tools to do what you want to do in the way you want to do it. Similarly, flexibility is also why you'd use Objective-C over Java or C# - because those languages may have some limitation as a result of their VMs that prevents you executing on the platform you want to execute on, speaking to the hardware you want to speak to, or, getting the performance you need to get.

      You can't write off Java and C# as being for different purposes then argue for Objective-C over C++ whilst ignoring the fact that C++ allows you to attain performance gains that Objective-C simply does not, or that C++ allows you to write code in a style that Objective-C does not. Even in C# I've seen some fantasticly readable code thanks to operator overloading that even Java would've made look fucking awful - i.e. a currency library that for example, if you added a USD currency to a EUR currency would convert the USD currency to EUR then add it on. In C# you might have something like:

      newFigure = ((currencyValue1 + currencyValue2) / 100) * (currencyValue3 + currencyValue4);

      Pretty readable, but in Java? -

      newFigure = (currencyValue1.add(currencyValue2) / 100).multiply(currencyValue3.add(currencyValue4);

      It's fucking awful. If you do anything with math it gets very hard very quickly to follow the math without operator overloading, but with operator overloading you can see, understand, and verify the mathematical algorithm in play quite easily.

      If you're talking about scenarios where C++'s advantages are not going to be born out over Objective-C then sure, Objective-C may be a better choice, but that's such an arbitrary talking point that you then can't rule out someone arguing the same about Java/C# over Objective-C based on a similarly arbitrary set of circumstances.

    140. Re:One good reason... by betterunixthanunix · · Score: 1

      Can you name a valid RTTI use that you don't consider a "hack"? Can you explain the existence of RTTI if not to solve this particular issue? And if you agree that RTTI exists to solve this particular issue, then what makes my intended use of it a "hack"?

      Well, it may just be a matter of opinion at this point, but if you are using RTTI to do something that your compiler could have done for you, then I would say you are writing a hack. This is not always the case, of course; dynamic_cast should be used if you are performing a cast down an inheritance hierarchy, but cannot guarantee that the cast will be valid (i.e. the client might use your code the wrong way, in which case an exception should be thrown). That is not the case here; here, you are using RTTI to implement a missing language feature (multiple dispatch); you might not call it a hack, but I would, just like I would call implementing objects in C by using structs and function pointers a hack.

      What can you not do with the library that you think is necessary and should absolutely be in the core?

      Well until C++11, lambda expressions -- yes, there was the Boost lambda expressions library, but that was not quite what was needed and it was not part of the standard. It would also be nice to have a built-in multiple dispatch facility (see above; the language only provides bits and pieces that can be used to implement multiple dispatch by hand), a more complete introspection system (not something I frequently use, but some people do), restarts or continuations (beyond what you can hack together with setjmp and longjmp), etc. The C++ language is missing quite a few modern features that other languages provide.

      I hope, for the sake of competence, that you are aware that all those examples you give can be fixed by proper debug libraries with custom smart pointers, custom array containers, custom allocators, and custom new, new[], delete, and delete[] overloads.

      Which is just a way of saying, "The standard is missing the things you need in those cases." If you are using the word "custom," then you are no longer talking about what the language itself provides.

      Also, thanks to being a native language, C++ can take advantage of all the available native debugging tools

      Which are not standardized across operating systems, hardware architectures, etc. If these things are necessary for C++ programmers to do their work effectively, then they should be part of the standard.

      Lastly, these are problems that you continue to have to deal in higher level languages, except you may not end up having security issues because of them,

      Even if that statement were true, it would be a huge improvement to move to higher level languages.

      Not without violating the principle of self-containment. So far in this thread everyone claiming that C++ exceptions have a problem are yet to demonstrate a single case in which catching a destructor exception would make any sense and does not imply bad design of their classes, so feel free to try...

      See my other post about restarts; basically, when an exception is thrown, it should be possible for the thrower to set restart points that the exception handler can jump to once the error is corrected (or perhaps if the error can safely be ignored, etc.).

      Because you might have cases in which functions called in the context of destruction (i.e.: functions called to free resources) may signal error conditions related to freeing resources, and in these cases the exception should be allowed to propagate so that the program can abort, because if your destructor, which is supposed to be in the best position to do the job, can not destroy parts of the object that it represents or ensure that the destruction doesn't leave side effects behind, then the program is in no condition to con

      --
      Palm trees and 8
    141. Re:One good reason... by Deorus · · Score: 1

      OK, but if the error can be corrected, then the destructor can proceed. Are you suggesting that the class should know both how to deallocate itself and how to correct external errors?

      No, I am suggesting that destruction time is too late tot hunk about external problems.

      Which means that there is a class of errors that the clients of the class will never have the ability to handle. Even something as simple as logging errors cannot happen under that rule.

      Yes, that class of errors is called a program crash.

      Then why sync at all? If it is not something that should be expected to work properly, then it is not something that should be done.

      From a design point of view, it makes no sense because your caller isn't expecting it; from a quality point of view, it makes your class a little more reliable.

      I am not seeing why that is any more wrong than throwing an exception from a constructor or a member function.

      Because unlike all other functions in a class, destructors are supposed to remain reliable even when the rest of the class is in an invalid state. If the destructors themselves become unreliable, then there is no way to destroy a class in an invalid state and the program has technically crashed because the principle of determinism has been violated.

      The approach you are suggesting is that if the destructor does not have any good way to deal with an error, the destructor should just fail silently. Even a global error flag is better than that.

      I never said that a destructor should fail silently, I said that exceptions unrelated to deallocation should be caught by the destructor because those do not compromise the destructor's purpose, which is to deallocate everything.

      We can have both reliability and performance, by allowing errors to be corrected.

      The current implementation already allows errors to be corrected.

      The ugly way to do that is to enclosing synchronization routines in loops, and to have catch blocks that take corrective action and then resume the loop.

      You catch exceptions to prevent your code from crashing, not to correct errors. Exceptions are supposed to be unrecoverable; there is no retrying unless you are in an interactive session with a user and that user specifically tells you to retry.

      So off the bat, you just dismiss the idea that you could ever correct the error and continue the execution of whatever code caused the exception to be thrown.

      Yes. If you could have done it right then you should have done it right.

      If you have an object that will write to a file, and you catch an exception that indicates the disk is full, what will you do?

      Depends on the code. If the code is part of a user interface which primary objective is to write to a file, then I will present the user with a pretty prompt and let them decide what to do. If the code is a function which primary objective to write to a file, then I will let the exception through because it is related to the task that I was expected to perform. If the code is a function which primary objective is not to write to a file but I called a function which primary objective is to write to a file, then i will catch and suppress the exception, because writing to a file is not part of the task that I was expected to perform. If the code is a function which primary objective is not to write to a file and I called a function which primary objective is not to write to a file, then I will let the exception through because this is a bug and the program must abort. In essence I only catch exceptions at user interfaces or when I am performing tasks that are unrelated to the purpose of the task that I am expected to be performing. For the pur

    142. Re:One good reason... by betterunixthanunix · · Score: 1

      From a design point of view, it makes no sense because your caller isn't expecting it; from a quality point of view, it makes your class a little more reliable.

      In another post, you claimed that C++ is only missing features, and there is no safety issue. Are you changing you mind about that one? The C++ standard requires a basic_filebuf to perform a sync in its destructor, and to allow that sync to silently fail.

      I never said that a destructor should fail silently, I said that exceptions unrelated to deallocation should be caught by the destructor because those do not compromise the destructor's purpose, which is to deallocate everything.

      OK, but what about errors that are the result of an attempt to free resources, like an I/O error that results from closing a file?

      There only responsibility that a destructor has is to free resources.

      Are we going to loop on this? Sometimes errors occur while resources are being freed. If an exception cannot leave a destructor, then the destructor is responsible for both freeing resources and for dealing with errors, or else you just abort whenever you have an error while freeing resources.

      And exactly does that solve your problem any better than creating a new stream and retrying the operation on it?

      As an example, the exception might have been thrown in the middle of writing record-oriented data (i.e. the logging facility threw an exception before the record was completely written); if you are unable to resume the operation, then you will either need to have a way to roll back the partially completed write (which may be ugly, e.g. if your stream was a socket), or a way to keep track of how much you had written (or the third option: you wind up with a corrupt file). Restarts provide a much cleaner solution here: if the error can be corrected or if it is safe to ignore, you can safely continue with the operation, without having to waste time on rolling things back and without having to keep redundant information about how much had been written (which is already tracked by the stream, except that the stream has no knowledge of your record structure). You also allow the clients of your class to decide priorities without having to know the details of your implementation: maybe logging is not important and can be skipped, or maybe logging is of equal importance to writing the records.

      --
      Palm trees and 8
    143. Re:One good reason... by Deorus · · Score: 1

      Well, it may just be a matter of opinion at this point, but if you are using RTTI to do something that your compiler could have done for you, then I would say you are writing a hack. This is not always the case, of course; dynamic_cast should be used if you are performing a cast down an inheritance hierarchy, but cannot guarantee that the cast will be valid (i.e. the client might use your code the wrong way, in which case an exception should be thrown). That is not the case here; here, you are using RTTI to implement a missing language feature (multiple dispatch); you might not call it a hack, but I would, just like I would call implementing objects in C by using structs and function pointers a hack.

      My compiler is pretty much doing it for me, and that its way of doing it; typeid is an operator. It's done this way because fortunately C++ is a static language and requires compile-time resolution, otherwise you'd be getting runtime error for things that could and should have been fixed before the code was even compiled.

      Well until C++11, lambda expressions -- yes, there was the Boost lambda expressions library, but that was not quite what was needed and it was not part of the standard. It would also be nice to have a built-in multiple dispatch facility (see above; the language only provides bits and pieces that can be used to implement multiple dispatch by hand), a more complete introspection system (not something I frequently use, but some people do), restarts or continuations (beyond what you can hack together with setjmp and longjmp), etc. The C++ language is missing quite a few modern features that other languages provide.

      In essence, you want to turn a static language into a dynamic language. Not going to happen. Regarding introspection, you can already do it with templates, except for structs, which for now you have to emulate using tuples. Restarts are something that I strongly oppose because they only address the representation of your program in memory, and your objects can represent a lot more than that.

      Which is just a way of saying, "The standard is missing the things you need in those cases." If you are using the word "custom," then you are no longer talking about what the language itself provides.

      Who cares? The tools are there, build your house! I could see the reason to complain about that in C, but in C++ I really don't. Even in C you have debugger implementations that pretty much do that for you (Valgrind).

      Even if that statement were true, it would be a huge improvement to move to higher level languages.

      Performance matters.

      Which are not standardized across operating systems, hardware architectures, etc. If these things are necessary for C++ programmers to do their work effectively, then they should be part of the standard.

      They are not necessary, but the advantage of native code is that it is very easy to debug and there are plenty of tools to do it.

      See my other post about restarts; basically, when an exception is thrown, it should be possible for the thrower to set restart points that the exception handler can jump to once the error is corrected (or perhaps if the error can safely be ignored, etc.).

      You should not be catching exceptions to correct errors.

      That is not true; if the error can be corrected, the destructor can continue executing and the program will be fine. That's the point of restarts.

      If there is an error that can be correct, then you should have avoided it in the first place. Exceptions are supposed to be unrecoverable.

      No, inexperienced programmers violate them as well. If you know how to write a cast (a novice level construct) then you know how to make an undefined conversion between pointer types.

      Ju

    144. Re:One good reason... by Deorus · · Score: 1

      In another post, you claimed that C++ is only missing features, and there is no safety issue. Are you changing you mind about that one? The C++ standard requires a basic_filebuf to perform a sync in its destructor, and to allow that sync to silently fail.

      I never said that the language didn't have safety issues, what I said was that the language was missing features, not safety, as in I don't need it to be safer, I just want more features.

      OK, but what about errors that are the result of an attempt to free resources, like an I/O error that results from closing a file?

      That's not an error resulting from attempting to free the resource, that's an error resulting from attempting to sync it. If you want to be clean (and slow) you can always fsync() first to separate the synchronization from the deallocation, otherwise you can just treat close() as a dirty call with double intent, throw exceptions relating to the deallocation task, and ignore the rest.

      Are we going to loop on this? Sometimes errors occur while resources are being freed. If an exception cannot leave a destructor, then the destructor is responsible for both freeing resources and for dealing with errors, or else you just abort whenever you have an error while freeing resources.

      Until you understand it, I am afraid so. All exceptions relating to freeing resources should be let through, because if a destructor can't deallocate, then the program has crashed; all other exceptions must be suppressed. How messy this ends up being depends on how messy the rest of your code is.

      As an example, the exception might have been thrown in the middle of writing record-oriented data (i.e. the logging facility threw an exception before the record was completely written); if you are unable to resume the operation, then you will either need to have a way to roll back the partially completed write (which may be ugly, e.g. if your stream was a socket), or a way to keep track of how much you had written (or the third option: you wind up with a corrupt file). Restarts provide a much cleaner solution here: if the error can be corrected or if it is safe to ignore, you can safely continue with the operation, without having to waste time on rolling things back and without having to keep redundant information about how much had been written (which is already tracked by the stream, except that the stream has no knowledge of your record structure). You also allow the clients of your class to decide priorities without having to know the details of your implementation: maybe logging is not important and can be skipped, or maybe logging is of equal importance to writing the records.

      Can you please give me an example of an error worthy of an exception that can be corrected without human interaction? Following that also provide an explanation as to why the caller would be better suited to correct the error than the callee when the caller isn't supposed to know anything about the callee's internals (this is how the self-containment principle is violated).

    145. Re:One good reason... by UnknownSoldier · · Score: 1

      > Was this pre c++03 or post?

      I left in 2010 about the time we were implementing C++0x (which eventually came C++11)

      The front-end was a nightmare to maintain because of the C++ ambiguity. (Especially templates)

      The back-end was relatively clean, because C & C++ look the same when you are working at the level of the AST and ILR (Abstract Syntax Tree and Intermediate Language Representation, respectfully.)

      > Except.. without even more ugly hacks to the preprocessor, there is no way to ensure any kind of tangible "safeness" to the macro system.
      I disagree. A macro system needs BOTH type safety AND lack-of type safety, because only the programmer knows when he needs one, the other, or both.

      Let's say we replace the preprocessor with a native C++ macro system.

      .macro LOG( $ file, # line, $ func, void expr )
      {
        printf( "%s(%d) %s\n", file, line, func );
        x
      }
       
      .macro IN( x ) LOG( __FILE__, __LINE__, __FUNC__, x )
       
      void foo()
      {
        IN( { printf( "Hello from foo!\n" ); printf( "Multiple statements.\n"); } )
      }
      void bar()
      {
        IN;
      }

      Where the types for the arguments are
      $ string
      # number (int)
      % number (float)
      void generic anything, can be optional

      Do we need a token to represent that the argument should be _x_ ?
      - character
      - pointer
      - array

      > I'd prefer removing obsolete C & preprocessor crap from C++. It would improve the language in every conceivable way.
      I agree! I'm interested in ideas in how this could be done.

      Currently you can't do stuff like this in C/C++ because of the idiotic preprocessor doesn't understand ':'

      #if !DEBUG // remove call in release build
        #define Foo::Bar
      #endif
      struct Foo {
        static void Bar( const char s, ... );
      };
      void test()
      {
        Foo::Bar( "%s", __FUNC__ );
      }

      I guess first we would need to replace:

      #include < >

      along with conditional defines, and macros.

      What else would need to be done if the preprocessor was treated like a first-class system?

    146. Re:One good reason... by UnknownSoldier · · Score: 1

      Thx grammer nazi.

      This is why I am a programmer and not an English major.

    147. Re:One good reason... by GrahamCox · · Score: 1

      This is why I am a programmer and not an English major.

      That's my point. You wouldn't make a syntax error when programming (and you wouldn't be allowed to), so you learn it and get it right.

      Incorrect apostrophes are just like having to deal with a compilation error when reading. It hurts! Or perhaps you feel computers are more important than people?

    148. Re:One good reason... by hazah · · Score: 1

      Then you're a shitty programmer. Any other strawmen?

    149. Re:One good reason... by UnknownSoldier · · Score: 1

      There is a time and a place for correct spelling and grammar.

      I couldn't give a fuck on /. if you get bent out of shape over negligible spelling. There are more important issues to worry about.

    150. Re:One good reason... by Anonymous Coward · · Score: 0

      Yep. But you might want to think about whether looking like an idiot is a small issue.

    151. Re:One good reason... by GrahamCox · · Score: 1

      Sounds like you're the one getting bent out of shape, e.g. using "fuck".

      There is a time and place for correct grammar and spelling, and it's all the time. The point is not that you think "it's on /., so I'm going to misspell and get all my apostrophes wrong". You either know how to write correctly or you don't, and if you do, you do it automatically, like anything you practice. If you don't know, that's fine, but don't try and claim the moral high-ground. You're the one who looks ignorant, so maybe learn what you don't know?

    152. Re:One good reason... by betterunixthanunix · · Score: 1

      I never said that the language didn't have safety issues, what I said was that the language was missing features, not safety, as in I don't need it to be safer, I just want more features.

      OK, good for you -- but we live in a world where the unsafe nature of C++ has created a brittle, vulnerable, unreliable software ecosystem. It is easy to be a snob and declare that the problem is that programmers are just too inexperienced to really make use of C++, but if that is the reality of the world, then the problem is C++, not the programmers.

      That's not an error resulting from attempting to free the resource

      Yes it is -- closing a file is, by your own admission, freeing a resource, and attempts to close a file might cause an I/O error.

      If you want to be clean (and slow) you can always fsync() first to separate the synchronization from the deallocation

      Except that the destructor might be called as part of a stack unwinding, in which case you will not get the chance to do that. Yes, I know, in your world if the destructor has an error that it cannot recover from on its own, the error should either be ignored or the program should crash.

      All exceptions relating to freeing resources should be let through, because if a destructor can't deallocate, then the program has crashed; all other exceptions must be suppressed

      In other words, allow potentially correctable errors to go unhandled, which is known as "failing silently."

      Can you please give me an example of an error worthy of an exception that can be corrected without human interaction?

      1. What do you think should be done when an error that is "unworthy" of an exception occurs? What determines whether or not an error is "worthy" of an exception?
      2. What difference does it make if human interaction is required? Most errors cannot be automatically corrected; many errors can be corrected by the user. It is almost never correct to allow errors to occur with no handling at all.
      3. You left out the part where it might be OK to ignore the error e.g. if an error occurs while logging you might want to complete higher priority tasks, or if a line of input is malformed the user might want to just skip it and read the rest of the input, or it might be acceptable for some operation to be partially completed, etc. Only the client of the class should be responsible for that sort of decision.

      Following that also provide an explanation as to why the caller would be better suited to correct the error than the callee when the caller isn't supposed to know anything about the callee's internals

      The caller does not need to know anything about the internals; the caller only needs to know that a particular kind of exception was thrown, and that the exception should be handled in some particular way. You streams classes don't know whether or not it is OK to ignore I/O errors, nor should they know, which is why an exception is thrown: the client of the class is better able to decide what to do about the error. A class for managing records should not know whether or not the user should be prompted to correct an error or skip over an error or if the program needs to run without user interaction, nor should the class know whether that prompt should be a GUI dialog, a beeping sound on a device with a button, or just a message to stdout followed by a read from stdin.

      Sure, you can do this without restarts, but it will result in a fantastically complicated design that will essentially implement a system of restarts, or an equally complicated design that will allow you to rollback operations and try them again. Or you can just punt on this, declare that errors that could be corrected but where the decision can only be made by clients of your class are not really correctable errors, and create software that is less reliable and that angers its users. How are any of these better options?

      --
      Palm trees and 8
    153. Re:One good reason... by benhattman · · Score: 1

      The only thing you listed as superfluous that actual qualifies is the struct/class business. Aside from that, your rant looks like of like admitting you don't fully understand or aren't comfortable with certain language features. What's worse, your justification to "reduce bloat" isn't even valid in many of these cases. Are diamond patterns bloat? If you eliminated them, how would you inherit multiple interfaces (all methods are pure virtual) that inherit from the same root interface? You couldn't do that without adding a new concept for interface classes (more BLOAT).

      Also, C++ standard library is the definition of minimalist for OOP languages. Pretty much all it contains (prior to C++0x11) is strings, containers (not even hashes), container algorithms, and iostreams. Despite that you'd eliminate half of those features? You honestly believe that qualifies as bloat? The JDK includes (not one, not two, but) three stream implementations, two UI implementations, specific versions of CORBA, and who knows what else. The fact is, standard libraries are good for standard things. The fact that std::transform is standard means when I bump into it and don't know what it does, I can quickly find documentation on it. That's much better than bumping into someone else's custom modify_each_value method and needing to read through there code to verify it works properly.

    154. Re:One good reason... by betterunixthanunix · · Score: 1

      My compiler is pretty much doing it for me, and that its way of doing it; typeid is an operator

      OK, so my C compiler pretty much does OOP constructs for me, because I can use structs and pointers.

      It's done this way because fortunately C++ is a static language and requires compile-time resolution

      Except, of course, for method dispatch. Multiple dispatch does not require a dynamic language, but it does require a more complicated dispatch system than what you see in C++. You can emulate double dispatching using a visitor pattern, and you can extend that to emulate multiple dispatch in general if you are willing to put in the effort. You can also implement your own version of a vtbl that supports multiple dispatch, but with the trade-off of losing static analysis (or having to jump through hoops to get it).

      Regarding introspection, you can already do it with templates

      Which is ugly and results in horribly complicated code.

      Restarts are something that I strongly oppose because they only address the representation of your program in memory

      Restarts also give you a clean way to deal with correctable errors, and more general continuations (e.g. call/cc in Scheme) provide clean solutions to a variety of programming issues.

      and your objects can represent a lot more than that.

      Except that relying on objects for everything results in vastly more complicated designs. Even when you are making proper use of OO design patterns, you will still wind up with more complicated designs for things like restarts, continuations, and multiple dispatch. C++11 introduced lambda expressions and lexical closures because of that problem -- it was very annoying to have to specify an entirely new class in situations where you only needed a closure, and it made code more complicated than it needed to be.

      Who cares?

      I thought this was a conversation about C++ and the C++ standard. If it is not, then why are we even bothering? You can get a garbage collection library for C++, you can get a library that allows you to create restarts, you can get a separate tool that adds AOP constructs, etc. You can just get a C++ implementation of Scheme, and suddenly all of Scheme's features are available in your program (or even better, you can use Guile and write some code in C++, and other code in Scheme)!

      This is not much different from the old Lisp practice of creating things like Prolog-in-Lisp. Sure, you can get libraries for these things, but if Prolog-in-Lisp does not make Lisp a logic language, then how can a C++ library turn C++ into something it is not?

      Performance matters.

      Sometimes that is true, but so what? High level languages do not necessarily perform poorly, and with today's compiler technologies the performance is generally comparable to C++ (unless you are talking about C++ programs that are loaded with hacks and tricks to squeeze the last bit of performance out; sure, I can grant that, but in most cases that is not what you see and when you do see it it is usually not portable). JIT optimizers can often do things at runtime that C++ compilers cannot do.

      There are also plenty of cases where reliability is more important than performance. Do you care more about the extra few seconds that you spend waiting at the ATM or about the ATM dispensing the correct amount of money?

      They are not necessary, but the advantage of native code is that it is very easy to debug and there are plenty of tools to do it.

      Debugging C++ programs is not easy in any sense of the term, and native code in general is not easier to debug than managed or machine independent code.

      You should not be catching exceptions to correct errors.

      So your streams class should know whethe

      --
      Palm trees and 8
    155. Re:One good reason... by seantide · · Score: 1

      I have always wanted to learn and use LISP, however I find it very hard to use the actual tools. C tools are very easy to use, and producing compiled code is very easy.

      Isn't part of the reason LISP isn't widely accepted because it is difficult to work with outside its now largely dead native environments?

      Just finding out how to produce standalone executables can be an exercise in frustration. I once did finally work out how to do it in Common LISP, but the process was ugly, cumbersome and the results were big and slow.

      I have rarely found the LISP community to be much help. My questions about how to use it for common programming jobs was met with "just start and stop your code in the LISP environment (manually)" or "there is a compiler that will do what you want and its only $5000".

    156. Re:One good reason... by GauteL · · Score: 2

      Lambdas are generally used to replace functors syntactically, but what I meant was STL algorithms, a set of standard templated methods that can be used on STL conforming data structures (either built in, or your own, as long as they you implement some basics such as iterators).

      If used properly, you can achieve some things nearly as quickly in C++ as you can with higher level languages. However, before lambdas you had to use a lot of functors to use them, which limited their elegance.

    157. Re:One good reason... by 0ld_d0g · · Score: 1

      I disagree. A macro system needs BOTH type safety AND lack-of type safety, because only the programmer knows when he needs one, the other, or both.

      Let's say we replace the preprocessor with a native C++ macro system. .macro LOG( $ file, # line, $ func, void expr )
      {
          printf( "%s(%d) %s\n", file, line, func );
          x
      } .macro IN( x ) LOG( __FILE__, __LINE__, __FUNC__, x )

      void foo()
      {
          IN( { printf( "Hello from foo!\n" ); printf( "Multiple statements.\n"); } )
      }
      void bar()
      {
          IN;
      }

      Where the types for the arguments are
      $ string
      # number (int)
      % number (float)
      void generic anything, can be optional

      Do we need a token to represent that the argument should be _x_ ?
      - character
      - pointer
      - array

      We could just port the macro system from High Level Assembly. Its pretty nifty. But in general I'm not convinced we even need macros because the macro syntax being partially disjoint from the underlying language introduces its own edge cases and weird behavior.

      We could simply mark code with a standardized compiler extension which is then evaluated like regular C++ during some some 0-pass. It easily could have access to the build toolchain data structures to make decisions using the build environment data and even change stuff like data packing. IIRC there have been several proposals for 'object oriented' (ugh) preprocessors but they have mostly been some meta language. I guess there is some value towards reduced implementation complexity in not having an entire language syntax be processed twice per translation unit, but there could be a subset of C++ used.

    158. Re:One good reason... by Anonymous Coward · · Score: 0

      Actually Ruby is a relatively simple language. A good job of making a textual style of Smalltalk (only with a horrible kludge of blocks). The bloated part may be the Ruby on Rails which is not the same thing at all. Ignoring libraries and looking just at the syntax/semantics of the language then Ruby is much simpler than C++.

      Lua is a simple language, Ruby is not. It is simple compared to c++, but that is true for most values of (languages without c++)

    159. Re:One good reason... by Anonymous Coward · · Score: 0

      I was nodding in agreement until you wrote:

      "And the people who complain about C++'s bloat generally like Python or Ruby, which are both just as bloated as C++, without the bonus of it's simplicity."

      WTF?

      How in the hell is either of these two languages even close to the bloat of C++? This stupidity can only be explained by you not knowing either Python or Ruby.

      You sir are a maniac.

    160. Re:One good reason... by Anonymous Coward · · Score: 0

      If you need an IDE to cover warts in your language, your language is broke. C++/C#/Java are all severely broken languages.

    161. Re:One good reason... by Anonymous Coward · · Score: 0

      Since when do you have to have multiple inheritence to write Proxy?

      What year did slashdot become the home of the moron?

    162. Re:One good reason... by Anonymous Coward · · Score: 0

      What is complex in Ruby?

      I suppose if you lack any formal CS training Ruby may look complex, but it is a very clean, very simple language.

    163. Re:One good reason... by Pseudonym · · Score: 1

      Since when do you have to have multiple inheritence to write Proxy?

      Bridge, not Proxy.

      What year did slashdot become the home of the moron?

      I have a 5-digit uid, and it's been thus for as long as I can remember.

      --
      sub f{($f)=@_;print"$f(q{$f});";}f(q{sub f{($f)=@_;print"$f(q{$f});";}f});
  3. Useless submission. by chemicaldave · · Score: 1

    How is this news for nerds? We already know this old story.

    1. Re:Useless submission. by MyLongNickName · · Score: 1

      Not useless. Not everyone who reads Slashdot is a developer.

      --
      See my journal for slashdot ID's by year. Mine created in 2005. http://slashdot.org/journal/289875/slashdot-ids-by-year
    2. Re:Useless submission. by Anonymous Coward · · Score: 0

      Yeah. The strong and weak points of C are well-known (by those who care to know), there is nothing new here and nothing to discuss.

    3. Re:Useless submission. by chemicaldave · · Score: 2, Insightful

      If you're not a developer then you don't care about the nuances of C.

    4. Re:Useless submission. by Anonymous Coward · · Score: 5, Insightful

      If you're not a developer then you don't care about the nuances of C.

      Of course. Curiosity is a bad thing. You should stick to what you already know, and never try to expand your knowledge beyond your field.

    5. Re:Useless submission. by Penguinisto · · Score: 3, Insightful

      Not necessarily.

      Some of us were developers at one point in our careers, some of us deal with tech that is extremely close to having to occasionally jump into source code, and some of us are hobbyists who just do it for the hell of it.

      Personally, I dabble in it once in awhile, but cannot stand to do it professionally. Why? Because I'd rather dream of naked nubile young ladies (grits optional) than to spend all my sleeping hours mentally untangling someone else's poorly-built code (or worse, my own occasional bork-ups).

      That, and it's kind of nice to not have to keep a laptop near the bed any more. :)

      --
      Quo usque tandem abutere, Nimbus, patientia nostra?
    6. Re:Useless submission. by Hognoxious · · Score: 1

      Indeed. If you weren't born knowing it there's no point in trying to learn it.

      --
      Confucius say, "Find worm in apple - bad. Find half a worm - worse."
    7. Re:Useless submission. by jd · · Score: 5, Funny

      Curiosity is real. Unless declared integer.

      --
      It's a small world and it smells funny; I'd buy another if it wasn't for the money; Take back what I paid (SoM)
    8. Re:Useless submission. by Anonymous Coward · · Score: 0

      If you're not a developer then you don't care about the nuisances of C.

      There, fixed that for you.

    9. Re:Useless submission. by sqldr · · Score: 2

      I've been using D a lot recently. It markets itself as what C++ should've been. In other words, it drops backwards compatibility with C (but can import C libs, and there's tools to help convert the headers to something useful), it has templates that don't confuse the hell out of everybody, but still has operating system level essentials such as pointers, inline assembler and the dreaded goto.

      It also has modern things like design by contract, syntactic sugar for mixins, efficient threads, built in variable length arrays and hashes (I've always hated STL), and you don't have to bother with header files (in fact, they don't exist), etc.

      It's a shame it's not more popular, but since I'm coding stuff for a hobby here rather than a job, that doesn't really matter.

      Let the flames begin!

      --
      I wrote my first program at the age of six, and I still can't work out how this website works.
    10. Re:Useless submission. by beta21 · · Score: 1

      And we never want Curiosity to be const

    11. Re:Useless submission. by TeknoHog · · Score: 1

      Life is complex. It has real and imaginary parts.

      --
      Escher was the first MC and Giger invented the HR department.
    12. Re:Useless submission. by Anonymous Coward · · Score: 0

      Personally, I dabble in it once in awhile, but cannot stand to do it professionally. Why? Because I'd rather dream of naked nubile young ladies (grits optional) than to spend all my sleeping hours mentally untangling someone else's poorly-built code (or worse, my own occasional bork-ups).

      Sir, I wish I had both a working account and the requisite mod points..
      I gave up the IT game for a number of reasons, but a major contributing factor was that, rather than sleeping the sleep of the just and having the requisite dreams of nubile females, I was having dreams(nightmares?) where reams of 'C' source code of the stuff I was working on scrolled before my eyes.
      I was frigging writing/debugging code in my sleep FFS!, I'd get into work the next day and implement the changes (hard one to explain to the boss “The code?, It is new, indeed, for I made it last night in a dream of strange cities; and dreams are older than brooding Tyre, or the contemplative Sphinx, or garden-girdled Babylon.”)

      so it was time to move on, and the nubile young ladies are back (with an occasional Perl relapse, but that's ok..isn't it?).

    13. Re:Useless submission. by Anonymous Coward · · Score: 0

      Real numbers are impossible to implement, and curiosity certainly isn't rational.

  4. Maybe because it compiles down to the metal... by skids · · Score: 5, Insightful

    ...and not some VM? Most of the popular languages these days are all dynamic. And they are very convenient and nice. But if you actually want to know what the machine is actually doing, and want to have a say in such things, C is the way to go.

    I mean, unless you want to, you know, use pascal or fortran or something.

    1. Re:Maybe because it compiles down to the metal... by interval1066 · · Score: 4, Insightful

      Although possible, and done, I have a hard time thinking of good reasons to write drivers in higher level or interpeted languages. Besides, most kernels are written in C, makes sense to write drivers in C. When some one trots out a kernel in Python then I'll jump on the systems work in python bandwagon.

      --
      Python: 'And then suddenly you have a language which says "we're all stuck with whatever the whiniest coder wants".'
    2. Re:Maybe because it compiles down to the metal... by slew · · Score: 4, Informative

      ...and not some VM? Most of the popular languages these days are all dynamic. And they are very convenient and nice. But if you actually want to know what the machine is actually doing, and want to have a say in such things, C is the way to go.

      I mean, unless you want to, you know, use pascal or fortran or something.

      Although "C" compiles down really very close to the metal, so does "C++" (and a host of other more modern languages). However, it's not that easy to take that next step to the metal. In between is a machine that virtualizes the registers (using register renaming techinques), virtualizes the memory (using difficult to predict caching, translation, and ordering operations), and reorders the instructions (speculation, branch target hiding, etc), and runs in a sandbox (under the os which is timeslicing between tasks and faulting and swapping in memory translations and maybe even simulating some instructions).

      Knowing what the machine is actually doing is often a mythical quest down the rabbit hole. Although I'm a big fan of "C+" (what I call the c++ subset that doesn't have all the crapola that I don't use**), I'm under no illusion that all you are really doing with C is using a more predictable translation strategy (e.g., static compile time translation) rather than some magical "metal" commanding language.

      ** +objects, +const, +templates, +-stl (some are okay), -overloading, -virtual inheritance, -rtti, -boost, etc...

    3. Re:Maybe because it compiles down to the metal... by Anonymous Coward · · Score: 1

      Everyone has their own subset of C++ that they like, which means when you get a bunch of programmers together on a C++ project, the odds of you running into the C++ misfeatures you can't stand to look at approaches 1.

    4. Re:Maybe because it compiles down to the metal... by serviscope_minor · · Score: 1

      c++ subset that doesn't have all the crapola that I don't use** ...

      -overloading

      How do you add two ints? How about two floats? Why is overloading bad?

      --
      SJW n. One who posts facts.
    5. Re:Maybe because it compiles down to the metal... by benjfowler · · Score: 1, Insightful

      OTOH, well designed, modern hotspot JITters can optimize in ways a static compiler can't.

    6. Re:Maybe because it compiles down to the metal... by Penguinisto · · Score: 2, Funny

      Even better - it allows you to actually make the results efficient. While most CS grads these days likely expect hardware tech to keep up with the bloat, there are a few folks out there who know what it's like to economize like hell when it comes to CPU or memory.

      Also, when you're seriously pushing limits, it's the performance difference between a 1982 Chevy Nova with a busted head gasket (.NET, I'm looking at YOU), and compiling yourself a Porsche 911 with all the Autobahn goodies included.

      --
      Quo usque tandem abutere, Nimbus, patientia nostra?
    7. Re:Maybe because it compiles down to the metal... by c++0xFF · · Score: 2

      +templates implies +overloading

      For example: the STL iterators use the same interface as pointers, which then lets you use templated algorithms that can accept an STL iterator or pointers into an array.

      Another example: your templated function needs to call fabs() on some variable of type T. Overloading lets the compiler pick the right one, even if it's a user-defined type.

      Overloading doesn't deserve the bad reputation. As long as you use it as a tool for specific reasons, it's wonderful to have. The most commonly-cited problem people have is when people overload operators (although this problem extends to any overloaded function) to do weird and unexpected things. Fortunately, this problem is discussed enough that it's rare to see someone do bad things with overloading.

    8. Re:Maybe because it compiles down to the metal... by Anonymous Coward · · Score: 0

      > How do you add two ints? How about two floats? Why is overloading bad?

      Add the string "0.5" to the string "1.0." with the '+' operator. Is the result "1.5" or "1.00.5" ?

      Is there an easy way to find out based on the syntax of the language, or do you have to dig into the class libraries you're including which may contradict each other?

    9. Re:Maybe because it compiles down to the metal... by ByOhTek · · Score: 4, Insightful

      That, and because of that, you can easily import a C library into any language without having to worry about compiler used, or bullshit like that.

      I have a C library. I can dynamically import it into C, Python, Java or C# fairly easy, on any platform, I don't even have to compile the library or have the same compiler. Want to do that with any other language (including C++)? You are in for some pain and suffering.

      --
      Self proclaimed typo king, and inventor of the bear destroying coffee table (patent not pending).
    10. Re:Maybe because it compiles down to the metal... by betterunixthanunix · · Score: 1

      I have a hard time thinking of good reasons to write drivers in higher level or interpeted languages

      To make auditing easier. Even if you are certain that some function does what it is supposed to do, how do you know there is not a dangling pointer somewhere that will overwrite some code in that function? How do you know that the array bound you received as input is valid, or that the null terminator for your string was even set? C is a pain to audit and debug because of the wild things that can happen with pointers -- having the right logic and having a working program in C are almost orthogonal.

      --
      Palm trees and 8
    11. Re:Maybe because it compiles down to the metal... by c++0xFF · · Score: 4, Insightful

      One of the best features about C++ is that you can define your own subset that you'll use. Don't want to use RTTI? Then don't! Worried about exception handling? Then don't use them! This is why C++ can never be slower than C -- in the end, just reduce that subset until you get to C and you're done. Beware, though, some of the features you just left out might actually improve performance over the C equivalent!

      However, this subset has to be defined on a project basis, and not left for individual programmers to decide for their own code.

    12. Re:Maybe because it compiles down to the metal... by tilante · · Score: 1

      If you really want to know what the machine is doing, write microcode.

    13. Re:Maybe because it compiles down to the metal... by lgw · · Score: 3, Interesting

      These days Java runtime bugs and security issues take up a significant portion of my time. There's no real advantage to "knowinf what the code really does" to be found in a modern hugh level language, because the VM isn't perfect, and anything short of perfect means you have to care aout that layer. And you don't have soruce for that layer, or an easy way to inspect it. Whenever I was a bit uncertain what the compiler would do with oddball corner-case code in C or C++, I could fire up the debugger and check the generated object code, achieving absolute certainty what was really happening.

      Wait till you have to debug your first memory leak in Java or C# - you'll be singing a different tune after that. At least in C, when a third-party API leaks memory you have all sorts of object-level tools available to get to the bottom of the problem, even without source. Bump into a JVM or CLR leak? Sucks to be you.

      --
      Socialism: a lie told by totalitarians and believed by fools.
    14. Re:Maybe because it compiles down to the metal... by skids · · Score: 4, Insightful

      To make auditing easier.

      Ehm... auditing dynamic languages at the level required for driver-level security is nearly impossible. No there are no dangling pointers. What there are is race conditions between the cleanup of the casually discarded memory item and it's availability for re-use. Churn in the underlying VM can change the consitency of lots of such behaviors without your code ever changing, so there's another headache. Add to that that almost all drivers for anything beyond a USB gadget are going to have to, mandatory, do some pointer arithmetic, deal with endian-swapped values, and deal with the differences between signed and unsigned fixed-width integer values, and it just makes the very idea of using a "modern" language for drivers threatens the sanity of anyone who ever wrote a production-worthy driver.

    15. Re:Maybe because it compiles down to the metal... by hxnwix · · Score: 3, Informative

      > How do you add two ints? How about two floats? Why is overloading bad?

      Add the string "0.5" to the string "1.0." with the '+' operator. Is the result "1.5" or "1.00.5" ?

      Is there an easy way to find out based on the syntax of the language, or do you have to dig into the class libraries you're including which may contradict each other?

      Always "1.00.5" unless you or one of your includes declared some extremely evil operators.

      Because they can lead to surprising behavior, c++ operators are usually defined with care so that they won't be accidentally invoked and don't do strange things when they are used (such as interpret strings as floating point values).

    16. Re:Maybe because it compiles down to the metal... by Anonymous Coward · · Score: 0

      > in the end, just reduce that subset until you get to C

      That hasn't been true since ages (C99 to be more precise).
      For example things like lack of designate initializers cause significant pain if you want to write high-performance code that is readable (can't declare spares arrays in a readable way - and no constructors aren't a good solution if you want best performance).

    17. Re:Maybe because it compiles down to the metal... by Anonymous Coward · · Score: 0

      I C dead languages.

      [Disclaimer: I took the low road -- RPN --> Assembly --> PostScript --> FORTH.]

    18. Re:Maybe because it compiles down to the metal... by Anonymous Coward · · Score: 0

      Never had that problem.

    19. Re:Maybe because it compiles down to the metal... by Anonymous Coward · · Score: 0

      I have a hard time thinking of good reasons to write drivers in higher level or interpeted languages

      To make auditing easier. Even if you are certain that some function does what it is supposed to do, how do you know there is not a dangling pointer somewhere that will overwrite some code in that function? How do you know that the array bound you received as input is valid, or that the null terminator for your string was even set? C is a pain to audit and debug because of the wild things that can happen with pointers -- having the right logic and having a working program in C are almost orthogonal.

      That's crazy talk! This is what documentation, code reviews, testing, parameter validation, and more testing are all for. Sloppy coding gives a sloppy product.

    20. Re:Maybe because it compiles down to the metal... by tibman · · Score: 1

      Adding strings has nothing to do with math unless you overload the operator to perform math functions. If you are indeed using a class that performs math on strings then open it up and look. You'd have to do the exact same thing if it was a .add(string x) method.

      --
      http://soylentnews.org/~tibman
    21. Re:Maybe because it compiles down to the metal... by Anonymous Coward · · Score: 0

      Always "1.00.5" unless you or one of your includes declared some extremely evil operators.

      Give the man a cigar. In C++ you have no way of knowing whether your operator has been overloaded in a particularly evil way without looking at the includes.

      With overloading, the syntax of the language is up for grabs.

    22. Re:Maybe because it compiles down to the metal... by ADRA · · Score: 1

      Funny that you're so good at diagnosing memory leaks, because in C you will spend a non-trivial amount of time detecting and fixing leaks, since any trivial omision or day to day bug could often lead to leaks. Now in the (fully) managed world, the chance of a truely leaked object becomes --substantially-- harder to accomplish (aka doing stupid things with static singletons, adding crap to an ever growing collection, etc..), and maybe because of that, the developers that use them aren't as equipped as those in the C/C++ world because by and large, they don't have to.

      --
      Bye!
    23. Re:Maybe because it compiles down to the metal... by pclminion · · Score: 1

      Add the string "0.5" to the string "1.0." with the '+' operator. Is the result "1.5" or "1.00.5" ?

      The result is the string "1.0.0.5". No sane person would expect otherwise, and no sane person would use a language where it wasn't.

      While it is true that an idiot can overload an operator to do something non-intuitive, this is not limited to operators. A programmer could give a function a non-intuitive (or outright misleading) name as well.

      Do you hold the C language accountable when somebody writes a function called MultiplyTwoIntegers() which actually subtracts them?

    24. Re:Maybe because it compiles down to the metal... by skids · · Score: 2

      While I agree to some point that processors do a lot of funky things these days, C is a pretty solid demarcation point for well-defined behavior that gets you close enough to the metal to do most of what you need to do down there. It's close enough that you can do some amount of optimizing for different CPU families, but not so close that you cannot write the majority of your code generically without worrying about performance.

      As to C++, it isn't just a pretty C. It may not have a VM but it does some pretty messed up stuff to implement OO calling conventions. C's function calls are implemented much more directly and predictably. You can be pretty sure all that is going to happen is a few stack pushes, rather than going dawdling around hashes of function signatures looking for a candidate because somehow a virtual got mixed in there. WIth C++ you have to get pretty affectionate with your compiler to know what features you can use, and how, without the whole pile of OO bricks falling on your head.

      (WRT branch prediction, It is the case today that CPUs have been optimized so much to run spaghetti code effeciently, that it has started to behoove some VM/compiler authors to write purposfully spaghetti-like code to take advantage of these accelerations. I find that rather ironic.)

    25. Re:Maybe because it compiles down to the metal... by skids · · Score: 3, Insightful

      I think the problem these days is an entire generation of coders who have never in their life experienced a UI that was actually so repsonsive that it was impossible to ever perceive a delay between your keystroke and its effects. They've been raised entirely on laggy windows textboxes and mouseclicks that just migt get around to doing something anytime now.

      They don't even know how slow their kit is running. They've never seen one run fast. So they consider similar results satisfactory when they write code.

    26. Re:Maybe because it compiles down to the metal... by Anonymous Coward · · Score: 0

      One of the best features about C++ is that you can define your own subset that you'll use.

      Sigh. As can everyone else.

      Did you miss the bit about "bunch of programmers on a project"?

    27. Re:Maybe because it compiles down to the metal... by TheDarkMaster · · Score: 1

      Exact. You have much more control over the performance/efficiency of the code. The only problem with C is that you need to know what you're doing, there's not a language for scriptkiddies.

      --
      Religion: The greatest weapon of mass destruction of all time
    28. Re:Maybe because it compiles down to the metal... by loufoque · · Score: 1

      C doesn't compile to metal. VHDL does.

    29. Re:Maybe because it compiles down to the metal... by Anonymous Coward · · Score: 0

      > The result is the string "1.0.0.5".

      You have no way of knowing that without seeing the code.

      > No sane person would expect otherwise

      Obviously, you've never worked on a team of programmers with different backgrounds.

      > and no sane person would use a language where it wasn't.

      Like C++, for example!

    30. Re:Maybe because it compiles down to the metal... by Darinbob · · Score: 1

      That's compiler doing the overloading according to strict language defined rules. As opposed to programmers defining their own style of operator overloading (most C++ poeple advise not to use operator overloading anyway except for the required iostream stuff). Overloaded functions are probably ok when used sparingly, but it can still cause confusion because you have two different functions given the same name. There is also the problem of what happens when a parameter can be converted into a different type, which of the overloaded functions gets called now becomes less clear to a lot of programmers.

    31. Re:Maybe because it compiles down to the metal... by 91degrees · · Score: 1

      To be fair, you could create a StringNum class that's derived from String, but handles numbers encoded as ASCII strings. I'd obviously overload the operators to do the calculations, and cast to and from a string, but if I add a String to a StringNum, which operator will it use? Will it cast the String to a StringNum and do the StringNum add, or will it cast the StringNum to a String and do an append?

      In this case, I think the answer is to think about this in advance, and make sure it's documented fully, and it's not unique to operator overloads, but it's an example of a realistic problem.

    32. Re:Maybe because it compiles down to the metal... by Darinbob · · Score: 1

      The problem with C++ in a low level environment is that it does add a lot of baggage. You need to essentially throw out a lot of the features and many programmers don't have the discipline to avoid the bloated or inefficient features.

      I do think C++ is much better with type checking. I like that if you use C++ that your memcpy routine will have proper const declarations in its parameters (this makes C++ much easier to use const declartions than with C).

      Practically though, C gets used because there are a lot of architectures with a C compiler but not a C++ compiler (at least not from the vendor). C is still the language that you will find everywhere. C++ just is not as ubiquitous.

    33. Re:Maybe because it compiles down to the metal... by shutdown+-p+now · · Score: 1

      I have a C library. I can dynamically import it into C, Python, Java or C# fairly easy, on any platform, I don't even have to compile the library or have the same compiler. Want to do that with any other language (including C++)? You are in for some pain and suffering.

      Doing it with C++ is extremely easy - limit your public API to the subset of C++ that is identical to C (i.e. global functions & structs), and declare all exported functions as extern "C". Many other high-level languages have some similar arrangements.

    34. Re:Maybe because it compiles down to the metal... by Khashishi · · Score: 2

      It's not about compiling close to the metal. It's about thinking close to the metal. With c, I can usually follow what the computer is doing by scanning through the lines of code. With c++, I can't. More things happen at instantiating an object or at the closing brace of a function than in the body of the function, and I have no idea what order things are being done in. With more abstraction, it's easier to see what the programmer intended a program to do, but it's harder to see what the program really does.

    35. Re:Maybe because it compiles down to the metal... by pclminion · · Score: 1

      You have no way of knowing that without seeing the code.

      That goes for all code, not just overloaded operators. I could write a function called ConcatenateTwoStrings() which actually converts them to floats and adds them, but I would be guilty of bad name choice. You do not blame that on the language do you?

      Obviously, you've never worked on a team of programmers with different backgrounds.

      If "team of programmers with different backgrounds" means "people with illogical thought processes," then no, I haven't, and I hope never to.

    36. Re:Maybe because it compiles down to the metal... by pclminion · · Score: 1

      To be fair, you could create a StringNum class that's derived from String, but handles numbers encoded as ASCII strings. I'd obviously overload the operators to do the calculations, and cast to and from a string, but if I add a String to a StringNum, which operator will it use? Will it cast the String to a StringNum and do the StringNum add, or will it cast the StringNum to a String and do an append?

      The error is this example was in deriving StringNum from String. This is a classic case of the "has-a" vs "is-a" question. A StringNum is not a string, because it fails the substitution principle (for instance, you can assign "Cat" to a String, but assigning it to a StringNum is nonsensical). Therefore, StringNum must not derive from String, and there will be no ambiguity

    37. Re:Maybe because it compiles down to the metal... by Anonymous Coward · · Score: 0

      That goes for all code, not just overloaded operators.

      Not true. Polymorphism introduces this problem where syntax varies by context. Not all languages suffer from this; in fact, most will insist on only ONE definition for an operator or function.

      (we'll ignore C's context-sensitive semantics for '&' and '*' to keep the peace)

      I could write a function called ConcatenateTwoStrings() which actually converts them to floats and adds them, but I would be guilty of bad name choice. You do not blame that on the language do you?

      I certainly would, if the language permits you to say "the word 'concatenate' means 'concatenate' except when it doesn't."

      If "team of programmers with different backgrounds" means "people with illogical thought processes," then no, I haven't, and I hope never to.

      Programmers who cut their teeth on dynamic languages may expect to be able to add numeric strings without worrying about conversion. That's not illogical, it's just different.

      Also, depending on your background, "&" or "." may be the most obvious operators to use for concatenation, and '+' would be nonsensical. Again, not illogical - just different.

    38. Re:Maybe because it compiles down to the metal... by lgw · · Score: 3, Insightful

      Yes, we've all heard that refrain: "mange code mens no memory leaks"; it's very last-century. Some of us on /. do this coding thing for a living, you know. That's not what I was talking about.

      There are memory leaks in the JVM itself. There are memory leaks in the CLR itself. Trust me, it really sucks to be stuck with one of those! Very hard to find and work around whatever's leaking, and you have no leverage at all over the vendor to get the leak fixed.

      And, you know, I never had a memory leak in my own code in nearly 20 years of assembly and C++ coding; not because I'm some rock star, but because there are reliable techniques to avoid them. It's harder in C: with the need to match acquire and release in every function, there will always be some human error creeping in. But with good coding standards it's a trivial problem with modern tools.

      --
      Socialism: a lie told by totalitarians and believed by fools.
    39. Re:Maybe because it compiles down to the metal... by HarrySquatter · · Score: 2

      Funny because Minecraft is a Java program notoriously bad at leaking memory and throwing null pointer exceptions. Maybe if he would have written it in C++ it would at least not be a slow, bloated hog?

    40. Re:Maybe because it compiles down to the metal... by serviscope_minor · · Score: 1

      That's compiler doing the overloading according to strict language defined rules.

      The compiler always overloads according to strict rules. The standard is very explicit about such things.

      As opposed to programmers defining their own style of operator overloading (most C++ poeple advise not to use operator overloading anyway except for the required iostream stuff)

      [citation needed]

      I simply don't believe you that most C++ people advise against it. It's just too useful.

      --
      SJW n. One who posts facts.
    41. Re:Maybe because it compiles down to the metal... by Anonymous Coward · · Score: 0

      C# memory leaks are pretty simple to track down and fix. Doubly so if you have VS with its "intellisense" available to you.

      Track down anything that implements IDisposable. Now you have a choice. You can:
      1) Beat it with a club until dead
      2) Beat the original developer with a club until dead
      3) Find where it goes out of scope and call .Dispose() or .Close() on it in a try/finally
      or 4) Wrap it in a damned using block like anyone with proper mental capacity would do. Then go beat the idiot that wrote it originally to death with a club.

      Also, COM is the devil. Any of that crap in managed code should be wrapped in a VERY well tested assembly separate from everything else.

      Aside from that, the CLR (1.1 and earlier notwithstanding) isn't very leaky. With Mono, YMMV.

      I don't work with Java or the JVM/JRE enough to know about it. From my limited experience, it seems to have more and worse issues.

    42. Re:Maybe because it compiles down to the metal... by Anonymous Coward · · Score: 0

      Worried about exception handling? Then don't use them!

      I hear that often, but don't know how to do that. The standard doesn't say a thing about it. Using anything like std::vector and the like risks you raising a std::bad_alloc.
      Unlike every other language, I always feel uneasy that I managed to get all corner cases right. Are all 3rd party libraries really exception safe? Did you catch all exceptions at every module boundary, call back function, ... ?

    43. Re:Maybe because it compiles down to the metal... by betterunixthanunix · · Score: 1

      But with good coding standards it's a trivial problem with modern tools.

      ...and yet there are memory leaks in the JVM and CLR.

      See, if what you are saying is true about memory leaks in C, then either the people working on the JVM and CLR are incompetent or else there is more to this story than you are letting on. I am inclined to think it is the latter, that there is more to stopping memory leaks than coding standards.

      In other words, if you are right, shouldn't that mean that writing one good runtime for Java or C# or Lisp would solve this problem once and for all?

      --
      Palm trees and 8
    44. Re:Maybe because it compiles down to the metal... by lgw · · Score: 1

      either the people working on the JVM and CLR are incompetent

      Let's just say Sun and Microsoft didn't use kernel programmers for these efforts. C has it's issues, to be sure, but "managed code" is not some magic bullet, and when you do have problems they're totally outside your control.

      --
      Socialism: a lie told by totalitarians and believed by fools.
    45. Re:Maybe because it compiles down to the metal... by lgw · · Score: 2

      The C#/.NET library code that "marshalls" objects when converting to/from unmanaged code uses COM under the covers. COM is indeed the devil - if anything needs to be given the baby seal treatment ...

      Otherwise, yeah, proper discipline around IDispose/using does wonders - but then, so does proper discipline around "what you acquire at the top of the function you must release at the bottom of the function" in C.

      Java is worse because it doesn't have "using" block or IDispose, so you get more boilerplate code, and therefore risk of human error with handle/resource leaks (of course, they're released eventually by garbage collection, but that just makes figuring out why that file/object was locked that much harder).

      --
      Socialism: a lie told by totalitarians and believed by fools.
    46. Re:Maybe because it compiles down to the metal... by DamnStupidElf · · Score: 1

      Which language would you choose to write a perfect VM? A suitable language for that kind of task presumably exists because Intel and AMD manage to produce chips that effectively implement a virtual machine in hardware with no bugs (most of the time). Why don't the authors of software virtual machines take the time to formally verify their software? It's unfortunate.

    47. Re:Maybe because it compiles down to the metal... by VortexCortex · · Score: 1

      Let's not forget, you don't use assembly to create the initial compiler for these "dynamic" languages... Most use C.

      I dropped from C++ back down to C for my projects because I realized I only used a very small subset of C++ -- The rest was handled by my scripting language modules (which were written in C).

      It was actually harder to hijack C++'s OOP model for the dynamic scripting language than to just write my own basic OOP in C that had the features I needed. I truly tried to NOT use C, boy that was a waste of time...

      Additionally, compiling my code in C is 64x faster than compiling it in C++

      Look, I still use C++ for when I want to do a one off little project, and can use their powerful STL and OOP and Templating, but when I get tired of working around C++ paradigms, and want to manhandle the system the way I want, I use C.

      Don't even get me started on ABI compatibility that supports different compilers...

      C is here to stay, why? Because that's what the OS is written in. Once the OS is written in something else, I might think of using it instead.

    48. Re:Maybe because it compiles down to the metal... by Anonymous Coward · · Score: 0

      It's not hard to provide C interface to your C++ library.

    49. Re:Maybe because it compiles down to the metal... by JonySuede · · Score: 1

      write JVM agents if you really are in deepshit but try visualVM first...
      I never stumble onto a JVM leak (I am sure that some must exist) but I did ran into application developers with no knowledge whatsoever of the java memory model. The most frequent sources of java leaks I saw in the field are unbounded caches that do not use WeakReference or graphic code that do not call dispose to free the system resources in combination to a heavy load preventing the finalizers execution.

      --
      Jehovah be praised, Oracle was not selected
    50. Re:Maybe because it compiles down to the metal... by Anonymous Coward · · Score: 0

      I agree

    51. Re:Maybe because it compiles down to the metal... by afgam28 · · Score: 1

      That's true, but it only really applies if your project is on the leaf node of the dependency graph (i.e. you're a library writer). Most applications depend on third-party libraries, and sometimes your only choices are to turn on RTTI, or to reimplement a huge library yourself.

    52. Re:Maybe because it compiles down to the metal... by lgw · · Score: 1

      I think that's less about the language, and more about the skillset and mindset of the developers. People who have done kernel and chip-level embedded work for years develop defensive habits that really help, but I don't think Microsoft or Sun employed people from that crowd to write their language VMs (which seems odd now, given that both had kernel hackers elsewhere in the company). Or it could just be the the in-processor VMs gets a lot more time and attention for just one platform (it's not that the JVM is bad here, it's just not perfect).

      --
      Socialism: a lie told by totalitarians and believed by fools.
    53. Re:Maybe because it compiles down to the metal... by Anonymous Coward · · Score: 0

      What are you talking about? The JVM has been open for years. Go get the code (C++) and use those object-level tools you love so much.

    54. Re:Maybe because it compiles down to the metal... by w_dragon · · Score: 1

      If you consider a vtable to be complicated to debug how do you manage normal functions? Is one extra level of indirection so difficult? The only time I found function calls difficult to debug was a unit test trick someone used where they edited a vtable after an object was created to change a couple functions to make something else testable. I have been shown C code where there was a hex array created and then the instruction pointer was set to the head of the array. You can write screwed up code in any language.

    55. Re:Maybe because it compiles down to the metal... by afgam28 · · Score: 1

      I think the problem these days is that an entire generation of coders think that the language, rather than the algorithm, determines whether a piece of software is going to be fast or slow. If we're talking about UIs, compare Unity and Gnome Shell. Unity and Compiz are written in C++ and can be incredibly unresponsive. Gnome Shell is largely written in JavaScript, and is very responsive.

      A lot of the higher level languages have slower GUIs because their GUI frameworks are designed more for modularity than responsiveness. They tend to have a lot of layers of indirection, which cause increased latency and slower responsiveness. Compare XUL to GTK+, for example.

      When people say they are using C for performance, what they usually mean is predictable performance, not necessarily higher performance. This is very important in real-time applications, and is why C is used heavily there even though a Java application running on a hotspot JIT can outperform it most of the time.

    56. Re:Maybe because it compiles down to the metal... by cerberusti · · Score: 2

      Diagnosing and fixing memory leaks is in fact trivial. Not only are there very good tools to tell you what is leaking, but it is extremely uncommon for someone to make this kind of mistake if they are an experienced C programmer.

      If this is a real problem in your code, it probably means you have too much code dealing with memory management. This is almost always a result of being a new programmer (or at least new to having this kind of control.)

      --
      I'm a signature virus. Please copy me to your signature so I can replicate.
    57. Re:Maybe because it compiles down to the metal... by cerberusti · · Score: 1

      You know there are no pointers which reference an improper address because you are the one who assigned the address.

      You know that your array is large enough because you either allocated an appropriate amount of space, or assured that you only read enough from your input to fill your static buffer.

      You know your string is null terminated because you put the terminating null there.

      Most of these will cause a crash, and are therefore easy to find... but these are the kind of mistakes that an experienced C programmer very rarely makes. The learning curve on C (or C++) is the real problem, as there is a period in every programmers career where they are new.

      --
      I'm a signature virus. Please copy me to your signature so I can replicate.
    58. Re:Maybe because it compiles down to the metal... by dkf · · Score: 1

      Doing it with C++ is extremely easy - limit your public API to the subset of C++ that is identical to C (i.e. global functions & structs), and declare all exported functions as extern "C". Many other high-level languages have some similar arrangements.

      But writers of C++ libraries don't do that in practice. They could, but they prefer to export their language features across library boundaries. To be fair, I would too in their position; it's much more useful within a C++ environment. The other key problem with C++ as a language for portable libraries is that it often depends on tweaked linking in the build-chain for some key features. Typically, when compiling and linking C++ these things are turned on automatically for the compiler/linker combination that you're using. However, they vary by build chain and if you're using the library from a non-C++ environment then you don't get them turned on and so get to find out rather more about what's going on under the covers than you really wanted to know.

      It's easier to produce a highly-portable library with C than with C++, as the basic ABI is more stable and there are fewer compiler tricks going on. Being boring and predictable and stable is a real bonus...

      --
      "Little does he know, but there is no 'I' in 'Idiot'!"
    59. Re:Maybe because it compiles down to the metal... by LizardKing · · Score: 1

      Java is worse because it doesn't have "using" block or IDispose

      It has "try with resources" which accomplishes the same thing.

    60. Re:Maybe because it compiles down to the metal... by betterunixthanunix · · Score: 1

      You know there are no pointers which reference an improper address because you are the one who assigned the address.

      Which is great if you never make mistakes. Except that people do make mistakes, and one dangling pointer can cause other pointers to be incorrect i.e. by overwriting their value. Debugging a pointer error is a giant pain, and it takes time away from debugging things that compilers cannot just do for you (i.e. errors in design or in program logic).

      You know that your array is large enough because you either allocated an appropriate amount of space, or assured that you only read enough from your input to fill your static buffer.

      Yet buffer overflows remain a real-world problem, even in code written by experts with years of experience.

      You know your string is null terminated because you put the terminating null there.

      Unless, of course, you had a dangling pointer somewhere that caused the null terminator to be overwritten.

      Most of these will cause a crash, and are therefore easy to find

      A lot can happen between the creation of an uninitialized pointer and a program crashing -- I have seen it happen. A dangling pointer that overwrites an integer that causes a buffer to overflow that causes another pointer to become invalid, and then the program crashes. Now your debugging process has to reverse that -- except the first thing you are dealing with is trying to figure out why a properly initialized pointer is pointing to an invalid address. It can take hours of work to find the original dangling pointer -- hours that should have been spent on more productive pursuits.

      these are the kind of mistakes that an experienced C programmer very rarely makes

      1. Those mistakes are still made by people with experience
      2. Inexperienced programmers are still out there writing code, and experienced programmers are often required to work with them
      3. Malicious programmers might try to hide these "mistakes," but craft them in a way that causes a backdoor; see e.g. the Underhanded C Coding Contest.

      The learning curve on C (or C++) is the real problem, as there is a period in every programmers career where they are new.

      All languages have a learning curve. The problem is that inexperienced C programmers do not just get "stuck" trying to figure out how to write the code they want to write (which is what the learning curve should be about); they often do not get "stuck" and wind up writing something that passes all test cases but still has some stupid pointer problem. The learning curve in C and C++ is almost as much about learning how to do what you want as it is learning about things you should never do but which are allowed by the language.

      --
      Palm trees and 8
    61. Re:Maybe because it compiles down to the metal... by ByOhTek · · Score: 1

      I've seen (I believe g++?) still mangle the function names in the final library output...

      --
      Self proclaimed typo king, and inventor of the bear destroying coffee table (patent not pending).
    62. Re:Maybe because it compiles down to the metal... by ByOhTek · · Score: 1

      Depending on the size of the library, it can still require enough extra work to not be worth the effort.

      --
      Self proclaimed typo king, and inventor of the bear destroying coffee table (patent not pending).
    63. Re:Maybe because it compiles down to the metal... by Anonymous Coward · · Score: 0

      I've worked with Java for a very long time, and so far as I know, I've never run into a JVM memory leak. If you don't know what you doing with class loaders and such, you can find yourself in a situation where objects are not being collected when you really want them to be. Java profilers are very good at helping you track down these types of issues. The "memory leaks" that I am familiar with in the JVM are not actually in the JVM: rather, they're in the standard library, where references to context class loaders are retained when you don't expect them to be. For instance, any Java web application, if the standard library retains a reference to your webapp's class loader, you are toast. There are ways to get around that, and as an experienced web application developer, you know how to diagnose and solve those problems.

    64. Re:Maybe because it compiles down to the metal... by shutdown+-p+now · · Score: 1

      The whole point of extern "C", aside from specifying the calling convention, is to prevent name mangling. It sounds like either a bug in g++, or - much more likely - something else being wrong.

    65. Re:Maybe because it compiles down to the metal... by bitingduck · · Score: 1

      I sometimes like to point out to people that I was never able to outtype Magic Window on an old 1 MHz Apple II+. I think I have managed to outtype every word processor I've used since then at least occasionally. Computers get faster fast, but the software often gets slower, faster.

    66. Re:Maybe because it compiles down to the metal... by antsbull · · Score: 1

      Weird how sites like ebay run off Java technologies (like WS02) isn't then? Seriously, you sound like you don't really use Java seriously - you are complaining about some obscure memory-leak that probably doesn't exist and is more likely to reflect some poor code in your system. I write financial transaction processing systems that run in an array of Tomcats, and run around a million transactions every half hour per tomcat - and we restart our tomcat's on order every 3 months just for maintenance or deployment. The memory stays static otherwise.

    67. Re:Maybe because it compiles down to the metal... by Anonymous Coward · · Score: 0

      Been noticing this 'lag' is becoming worse and worse..
      good to know there's people out there that notice the difference.

      Too bad the current generation rather waste clock-cycles, and hope for the machine to get faster instead of writing proper code.

    68. Re:Maybe because it compiles down to the metal... by Anonymous Coward · · Score: 0

      Any Python is built on top of........?

    69. Re:Maybe because it compiles down to the metal... by lgw · · Score: 1

      I'm sure you're right and Java is the bestest language evar!

      Every language has its issues. You can do great things with most of them anyhow. My real complaint with Java is the endless boilerplate code - so verbose and inelegant. C has similar issues. Not a big fan of either, but they're both fine as the issues with each aren't that big of a deal.

      --
      Socialism: a lie told by totalitarians and believed by fools.
    70. Re:Maybe because it compiles down to the metal... by lgw · · Score: 1

      Good point! I forgot Java 7 caught up in that way. (Still trying to drag my own coding group off of Java 5 - management mindlessly panicked at the suggestion of using scary new Java 7 langauge features. Sigh.)

      --
      Socialism: a lie told by totalitarians and believed by fools.
  5. Good habits by Bucky24 · · Score: 5, Insightful

    Personally the thing I like most about C is that it's not "safe". It doesn't take care of a lot of memory management for you and you can easily eat up all the memory or introduce a buffer overload vulnerability if you're not paying attention. It forces programmers to actually look at what they're doing and consider what it will do in the long run, and causes good coding habits to form. I think the majority of people who dismiss C as "too hard" are coming from Java programming. C gives you a lot of power, but, as the well-cliched saying goes, "with great power comes great responsibility".

    --
    All the world's a CPU, and all the men and women merely AI agents
    1. Re:Good habits by localman57 · · Score: 5, Informative

      Exactly. My company does a lot of different things from embedded systems to web interfaces, and, generally speaking, the C guys write better Java code than the Java guys write C code.

    2. Re:Good habits by jmsp · · Score: 5, Insightful

      > It forces programmers to actually look at what they're doing

      OMG! There. That's where all the hate comes from.

      --
      (Programming in C since 1984)

    3. Re:Good habits by jellomizer · · Score: 4, Interesting

      Problem is the diligence that is required. A C developer is a really good coder when they do their work in an other language. However for large projects, C doesn't make too much sense, because you need to expect your developers to be on their A Game in the course of the project. A developer is porting their proof of concept code into production, right near lunch time, and he is starving, and some of the other guys are waiting on him to finish up, because they are starving too, might mean some code got copied in, and put into the production set, without full though. Because the Proof of Concept code worked, it may pass many layers of Quality Check (and we all know most software development firms have very poor QA teams) Once it leaves and goes to the customer, it could be wide open to a security problem.

      Every Developer thinks they are the best developer on earth about 50% of them are actually below average. C is a great teaching tool, I wish most colleges still used it, and didn't switch to .Net and Java. However once you go into production, unless you really need the C performance (and you can code highly optimized C) going with other Languages that are a little more protected is a safer bet.

      Hire a C developer... Give him a higher level language, and you will probably get really good code.
      Hire a C developer have him program C, you are setting up a time bomb, where once they miss a beat you are screwed.

      --
      If something is so important that you feel the need to post it on the internet... It probably isn't that important.
    4. Re:Good habits by localman57 · · Score: 1

      The funny thing about this, is how often higher-level languages let you sweep things under the rug. For instance, how often have you seen some hack take a big, complicated function, and call it inside a try/catch block that just throws out the exceptions? In C, these programs usually crash spectacularly. If you run them under GDB or similar, you can see where they crashed.

    5. Re:Good habits by Anonymous Coward · · Score: 0

      Your Java guys must write the worst C code known to man, then, because every C-coder-writing-Java that I've encountered just tries to write C code wrapped in a Java class. And then they mess it up.

    6. Re:Good habits by benjfowler · · Score: 1

      I've seen "C" written in Java. And it ain't pretty.

    7. Re:Good habits by OTDR · · Score: 1

      Exactly! Sadly, I'm old enough to see code performance improved more often by the application of better hardware than by better coding practices and smarter software designs. A poor coder will code poorly regardless of the language and C can be just as safe as the next language in the right hands, or as dangerous. C is nice to have around in many circumstances where resources are few (the embedded world, for example) or when you really need to get down to business with minimum overhead and fuss (like the realtime simulation world).

      C holds your hand less. C let's you excel when you need to. C reveals your incompetence when you're lazy. If your application doesn't need it or you don't know how to use it, go write an Excel macro instead. :)

    8. Re:Good habits by ShanghaiBill · · Score: 5, Insightful

      the C guys write better Java code than the Java guys write C code.

      My experience is that the C guys (and gals) often write better Java than the Java guys write Java.
      Programmers who have never written in C (and/or assembly) often have a poor understanding of how computer actually work.

    9. Re:Good habits by Anonymous Coward · · Score: 1

      So have I, and C is simple, efficient, and EASY.

    10. Re:Good habits by jellomizer · · Score: 1

      In C, you hope these programs [strike]usually[/strike] crash spectacularly. FTFY
      When they do not, that is when the real trouble exists, and could destabilize your application further down the line.

      The Try Catch when used properly. Makes sure if there is a problem, you leave your program cleanly. It is open for abuse yes... But so is any language command.

      --
      If something is so important that you feel the need to post it on the internet... It probably isn't that important.
    11. Re:Good habits by Anonymous Coward · · Score: 0

      This has been my experience as well. I don't know many C programmers that translate well to non C languages..because most of the patterns they don't run into much in their world. They tend to write mostly large blocks of if/else and such

    12. Re:Good habits by Bucky24 · · Score: 1, Insightful

      I totally agree. My point was that C promotes good habits. It's absolutely not a language made for large projects. I suspect that a lot of this is because large projects of that type really didn't exist back when C was being developed.

      --
      All the world's a CPU, and all the men and women merely AI agents
    13. Re:Good habits by localman57 · · Score: 1

      Yeah, that's fair. I may be biased because around here when the C guy messes up a java app, it crashes. When the Java guy messes up a C application, a brushless motor goes berserk and burns itself out. We don't let crap like that happen on production servers or on really expensive hardware, so not much damage is done in either case, but the Java guys' reputations suffer from the fact that you can't smell a C programmer's Java app crashing...

    14. Re:Good habits by Anonymous Coward · · Score: 1

      Yeap. C guys know to look for memory leaks in Java, whereas Java programmers ignore them all.

      If anyone ever tells you that memory leaks are impossible in Java, stay away from them.

    15. Re:Good habits by Mike+Buddha · · Score: 1

      I'd tend to believe that the C guys have more experience than the Java guys. Could this possibly have anything to do with their relative capabilities?

      --
      by Mike Buddha -- Someday the mountain might get him, but the law never will.
    16. Re:Good habits by Raenex · · Score: 2

      It forces programmers to actually look at what they're doing and consider what it will do in the long run, and causes good coding habits to form.

      It forces programmers to spend a lot of time thinking about low-level issues. As an example, anybody who has done string manipulation in C versus Perl (or Python, etc.) knows what I'm talking about.

      Rather than patting themselves on the back about how they manage to work with a high-level assembler, most developers want to use productive tools and can afford to sacrafice some memory in exchange.

    17. Re:Good habits by Anonymous Coward · · Score: 0

      I feel fortunate that I arrived at Java from C through C++. Having done so gives me perspective and a lot of good coding habits along the way. It provides me perspective on the trade-offs.

    18. Re:Good habits by c++0xFF · · Score: 1

      Put it this way ... when a C coder writes something in Java, it usually works even if it looks ugly. When a Java coder writes something in C, it's usually leaks memory like a sieve, only works with the specific inputs that they used to test, constantly walks off the ends of arrays, breaks when you cough too loudly, and took forever to write.

      Here's why: you can pretty much translate C code into Java without too much hassle, as most of C is a simple subset. A few syntax changes here and there, and you're done. Any language or library features that Java doesn't have can be redone in a different way, which is something most C programmers are comfortable doing.

      Translating Java to C is another matter. First you have to think about memory allocation, which is a concept that the original Java didn't have to worry about. But the bigger problem is the relatively thin standard library for C vs Java. You have to hand-code a lot of stuff that Java has by default. Like dynamic lists, for example. What a C coder has to do every day, many Java programmers haven't had to deal with at all. And the end result is ugly, buggy code.

    19. Re:Good habits by fahrbot-bot · · Score: 1

      When the Java guy messes up a C application, a brushless motor goes berserk and burns itself out.

      So, they write controller code for Iranian centrifuges? :-)

      --
      It must have been something you assimilated. . . .
    20. Re:Good habits by Anonymous Coward · · Score: 0

      I thought one of the major selling points of C#/Java was memory management. So you wouldn't have memory leaks and what not. Do you have to really fudge it up to introduce a memory leak or is it reality simple? Do they have tools like valgrind for Java/C#? If so why wouldn't they be common place to use them? I'm not a Java / C# programmer so maybe that's why I had the misunderstanding.

    21. Re:Good habits by nebosuke · · Score: 1

      Personally the thing I like most about C is that it's not "safe". It doesn't take care of a lot of memory management for you and you can easily eat up all the memory or introduce a buffer overload vulnerability if you're not paying attention. It forces programmers to actually look at what they're doing and consider what it will do in the long run, and causes good coding habits to form.

      Unfortunately, that's not how people work. C neither enforces diligence nor does it cause good habits to form. All it does is tend to make the consequences of laziness and bad habits more serious. This is analogous to how gun ownership requires good safety habits (given the underlying assumption that you want to avoid unintentional harm to yourself or others), but simply owning a gun doesn't force you to practice them.

    22. Re:Good habits by Hognoxious · · Score: 1

      Unix is something you could knock out solo over a weekend?

      --
      Confucius say, "Find worm in apple - bad. Find half a worm - worse."
    23. Re:Good habits by bhcompy · · Score: 1

      Which is to say that C will notify you that you are terrible at programming, rather than let you get away with being terrible because the language(and/or compiler) is more forgiving like Java or VB

    24. Re:Good habits by ArsonSmith · · Score: 2

      of course, programing in C is experience while programming in Java is idle waste.

      --
      Paying taxes to buy civilization is like paying a hooker to buy love.
    25. Re:Good habits by ADRA · · Score: 1

      I was a C guy who became a Java guy. Why? Its stupidly simple to just do your work in Java instead of working with 1600 miute details of busy work that chokes productivity away from what I'm really trying to accomplish. Java has its busy work which a lot of people have been griping about for years, but its leaps and bounds from C in terms of random crap that you always have to worry about whenever your trying to accomplish something simple and straight forward.

      I would not deny that every developer should at least learn on C to get familiar with the inner workings of higher level languages, and the best practices on the micro level around it, but if we all went back to C or C++, productivity would drop off the fall off the cliff (not even the learning curve, bugs etc..), just the amount of extra effort to make X from one language to another.

      --
      Bye!
    26. Re:Good habits by Anonymous Coward · · Score: 0

      Do you have to really fudge it up to introduce a memory leak or is it reality simple?

      More on the "fudge" side.

      "True" memory-leaks in Java--which like C's memory-leaks aren't things you can exactly recover from--generally involve doing "fancy" or edge-case stuff. For example, interacting with native code via JNI, thoughtless use of class-loading and static variables, abusing special optimization features like String.intern(), or creating many many of files and marking them for deletion when the JVM exits.

      Most people's "memory-leaks" in Java aren't really leaks in the same way, they're simply places where they're storing references to the object in a data-structure and didn't remove them. It's analogous to the problem of a stack where you push something on and forget to pop it off. The program still knows exactly what's been allocated, and why it is still considered "in use", and you can still look and poke at it in a debugger...

      For example, you might have an class Foo that can fire events when it is modified. Therefore each Foo instance can multiple references to FooListener instances which will be notified when a change occurs. Your FooListener instance will hang around, for as long as a the Foo it was listening to also exists. To solve this kind of "one-way interest" problem, you just use weak references.

    27. Re:Good habits by ShanghaiBill · · Score: 2

      I thought one of the major selling points of C#/Java was memory management.

      Java has automatic memory management, and it works well most of the time. But it doesn't work so well if you have cyclic references (it can detect some, but not all cyclic references) and it will not free up references to unused memory that happen to be tucked away in persistent data structures. These are easy to deal with if you understand why these cases happen. Good C programmers are trained to recognize these situations. Java programmers are trained to think memory management is "magic".

      Do they have tools like valgrind for Java/C#?

      Some who has never learned to manage memory manually with malloc/free, is not going to see the need for these tools, nor understand how to use them.

    28. Re:Good habits by Anonymous Coward · · Score: 0

      I totally agree. My point was that C promotes good habits. It's absolutely not a language made for large projects. I suspect that a lot of this is because large projects of that type really didn't exist back when C was being developed.

      C was developed for writing operating systems. If that's not your idea of a large project, then I don't know what is.

    29. Re:Good habits by Bucky24 · · Score: 0

      Re-read what I said. Nowhere did I state it was impossible, just that it shouldn't be done. Don't knee-jerk your responses, it degrades the quality of the site just a little bit more.

      --
      All the world's a CPU, and all the men and women merely AI agents
    30. Re:Good habits by ADRA · · Score: 1

      WTF is a Java guy? Someone who's never taken univerity? Never gone to school? How many collage courses have you been to where C was not on the curriculum? Your experience is absolute garbage. Step back and look at these people's: Age, Experience, Training and then tell me its their mythical 'language'-guy affiliation that makes them better or worse developers.

      IMHO, the many 'C-guys' I've worked with write really crappy Java for at least 1.5 years before they just get it, and usually by then they aren't C guys anymore, because they get a lot more done in Java, or C#, or whatever. It won't be as performant but typically if the language of choice for a project is open for debate, then a mainstream higher level language is typcially the safer and better (over the life of the product) choice.

      --
      Bye!
    31. Re:Good habits by Anonymous Coward · · Score: 0

      >Every Developer thinks they are the best developer on earth about 50% of them are actually below average.

      Knuth's still alive so 90% are below average. (Used to be 99% but Ritchie died.)

    32. Re:Good habits by bobbied · · Score: 1

      I'd tend to believe that the C guys have more experience than the Java guys. Could this possibly have anything to do with their relative capabilities?

      Nope.. It's because C is more than 25 years old and Java only half that. Computer Science schools have been truing out mostly Java programmers for the past decade. So the average professional with C training and experience will have more years of experience overall.

      Many software engineers don't understand what the issue here really is. It's not about C being better than Java, Perl better than Python or csh better than sh. These are only tools we use to develop our software. It's about using the RIGHT tool for the job.

      I've argued with fresh CS graduates about their insistence that Java is a better tool for everything programming. To those who only have one tool in the tool box their arguments make sense. The real issue is having as many tools as you can in your tool box and knowing when and how to use each one. Well stocked tool boxes come with experience.

      Writing a device driver? Please don't use Java... A GUI? Dig out the Java SDK. Something in-between? We might need to talk about it.

      "If the only tool you have is a hammer, all your problems start looking like nails..."

      --
      "File to fit, pound to insert, paint to match" - Aircraft Maintenance 101
    33. Re:Good habits by TheDarkMaster · · Score: 1

      LOL! Thanks, you made me laugh so loud that I spilled my coffee :-)

      --
      Religion: The greatest weapon of mass destruction of all time
    34. Re:Good habits by Darinbob · · Score: 1

      Also many C programmers know what Java is doing behind the scenes, they may have even written parts of a VM in the past. They'll know which operations are likely to be fast and which are likely to be slow. The person who learned on Java and who rarely looks outside that world may often not have a good feeling for what is efficient or not. To be fair though, in many Java application environments being efficient is not that important; they're on fast machines with tons of memory and most time is spent waiting for events.

      (For similar reasons, programmers who've used assemblers tend to write better C code in my experience)

    35. Re:Good habits by Sperbels · · Score: 1

      I think a lot of you guys make stupid generalizations about people based on what languages someone is most experienced with. The scary thing is, some of you guys are probably interviewing potential employees and you're dismissing perfectly fine engineers based on these beliefs.

    36. Re:Good habits by gbjbaanb · · Score: 1

      A "java guy" is a guy who codes using java, whether that's because its his exclusive or only language. I'm told that some places only teach Java, that does happen with some workplaces I know (though it's typically C# that gets taught now)

      I always think that Java (and C#) is a neither-good language. If you want performance, you'd do it in C/C++. If you want programmer productivity, you'd do it in Python or Ruby (or similar). The Java-based languages fall into a middle ground that you could say (if you were kind) is more performant than the scripting langauges and quicker to develop than C/C++. But the more realistic way of looking at it is that its not as good as either extreme depending on your task.

    37. Re:Good habits by Darinbob · · Score: 1

      Would this depend on the VM? Most good garbage collectors won't have leaks (reference counting should only be used as an example of how not to do GC). However a poor program could keep references around to stuff that should be garbage.

    38. Re:Good habits by Darinbob · · Score: 1

      I think there are far more jobs for Java programmers. So if someone is a mediocre programmer then getting a job where there are hundreds of others doing the same thing will hide the mediocrity better. If there are only 5 C programmers on a team then it's hard to hide the fact that you're the guy pulling everyone down.

    39. Re:Good habits by Anonymous Coward · · Score: 0

      I still remember the day back in 1982 when I sat down with a C compiler and figured out pointers for myself.

      I made dozens of mistakes that day, and I learned a huge amount. I learned what happens when you forget to malloc, or if you double-free. I printfed pointers with "%d" and figured out how scaled pointer arithmetic works. I saw the unpredictability that can happen if you use uninitialized pointer variables. I satisfied my curiosity about indexing p[-1], and indexing beyond the malloced size. I satisfied my curiosity about how many times I could call malloc. I explored questions like 'why can you use "&x", but you can't use "&(&x)" ?'.

      To use a car analogy, I drove stupidly and recklessly around a big junkyard and smashed my car into all the other junkers just for the hell of it.

      And it was, by far, the single most valuable day of programming education I had in my entire life.

    40. Re:Good habits by crunchygranola · · Score: 1

      I am a programmer from way back, I once counted up how many different languages and major language variants I had actually written code in and came up 40 or so (several assemblers, etc.). Today I write code almost exclusively in Java (followed by Python and Mathematica) because it is the most productive tool for what I want to do - solving problems and building systems (though I am looking at Scala now).

      But I agree that there are a lot of mediocre Java programmers running around today. In fact I run across a lot of "application assemblers" - people who build systems using frameworks and the Java foundation classes who can't really program at all. It is a testament to the power of the OO paradigm and the maturity of Java and the frameworks that this is even possible. But I never hire these people. They understand nothing about efficiency or proper multi-threaded design, and those systems are terribly inefficient and often dangerously flawed.

      I am tempted to say that the safety and high level abstraction of the language has enabled/encouraged barely competent programmers to enter the field. But then I remember all of the frighteningly horrible FORTRAN programs I ran across back in the day...

      --
      Second class citizen of the New Gilded Age
    41. Re:Good habits by Alamais · · Score: 4, Insightful

      Having recently had to learn TI assembly to do things on some strangely designed DSP boards, I really do think it should be more widely taught. Memory management takes on a whole new meaning once you've had to fit your program (data acquisition and FFTs) and data into one shared 10kword RAM block which has some hardware-reserved blocks and various alignment requirements. I had plenty of conceptual understanding of how computers worked beforehand, but now things like shared busses, registers, stacks, addressing, interrupts, etc. have much more direct meaning to me, and I feel a lot more grounded even when coding in higher-level languages.

      ...Not to mention I feel grateful now that I don't often have to use ASM.

    42. Re:Good habits by FormOfActionBanana · · Score: 1

      I'm not sure if you're joking, but resource leaks in Java are a real problem.
        - leaked file handles
        - leaked database connections
        - leaked streams
        - leaked GUI objects
       

      --
      Take off every 'sig' !!
    43. Re:Good habits by Xiaran · · Score: 2

      I've come across worse than this. I have encountered java only developers that think *everything* is managed in java. So database connections don;t need to be closed as I was told by one young developer... while trying to figure out why the Notes DB he was connected to was periodically failing due to it running out of connections.

    44. Re:Good habits by scobiej · · Score: 1

      And what's wrong about having to on your A game? A good C programmer is usually a very diligent programmer. I certainly can't say the same for all the Java boys and girls (although I know there are some fantastic ones out there also).

    45. Re:Good habits by Anonymous Coward · · Score: 0

      no, a "java guy" is someone who not only went to university but also went to an university that had only java straight from introduction to programming course. java guy in this context is someone who wouldn't be able to use javac without eclipse.

      plenty of universities in the world where you don't touch c unless you choose some advanced embedded course, too.

      then again imho c++ circa 1993 is much more readable than all the new flavors(well, I kinda like qt style though), usually though in my experience language gets chosen though because it's available and deployable... javascript yuck.

    46. Re:Good habits by patchmaster · · Score: 1

      The problem you describe is shoddy development practices. This has nothing whatever to do with the language being used. No language is going to protect you from an organization that allows rushed code to go directly to a customer without code review, thorough unit test, integration test, and V&V testing.

      Dangerous, crap code can be written in any language. It is not unique to C.

    47. Re:Good habits by Lord_Naikon · · Score: 1

      Can you give a concrete example where the GC fails to detect a cyclic reference? IIRC Java's garbage collector eventually traces through all stacks looking for live objects; any objects not referenced on any stack, directly or indirectly through other live objects, are then deleted. Regardless of any cyclic references between dead objects, the outcome should be the same.

    48. Re:Good habits by HornWumpus · · Score: 1

      You're just not a good enough programmer to use a calculated GOTO.

      Truth: I once saw code that used a linenumber variable to control what logic ran next. I would have broken all the original programmers fingers if I could have found him.

      --
      John McAfee 'It was like that time I hired that Bangkok prostitute; to do my taxes, while I fucked my accountant'
    49. Re:Good habits by tzanger · · Score: 1

      I have no idea what you're talking about. I too have been doing embedded systems design (hw, sw, the whole kit and kaboodle) for about the same amount of time as you and no, I do not think that C is too hard. Not at all.There are little things I'd like to change about it, but not because it's too hard.

    50. Re:Good habits by tzanger · · Score: 1

      Problem is the diligence that is required. A C developer is a really good coder when they do their work in an other language. However for large projects, C doesn't make too much sense, because you need to expect your developers to be on their A Game in the course of the project. A developer is porting their proof of concept code into production, right near lunch time, and he is starving, and some of the other guys are waiting on him to finish up, because they are starving too, might mean some code got copied in, and put into the production set, without full though. Because the Proof of Concept code worked, it may pass many layers of Quality Check (and we all know most software development firms have very poor QA teams) Once it leaves and goes to the customer, it could be wide open to a security problem.

      What you wrote has absolutely nothing to do with C and everything to do with human beings. If your code is not going through a review process where you have a team go through a module at a time, preferably over beer and pizza... you're already creating this problem. Diligence is required in any language, and I'd argue for any profession.

    51. Re:Good habits by epyT-R · · Score: 1

      yeah but when simple applications gobble 50+MB of ram and suffer laggy GUIs on modern desktops, it's unacceptable.. Java and .NET apps are where I see this the most, which makes me avoid them when possible.

    52. Re:Good habits by cerberusti · · Score: 1

      That last time I did that...

      The client asked if I could give them a Java version of what was an already existing C program. The logic was easily translatable to Java, so I did that.

      What happened of course is that I copied it to a Java class, changed the few things I needed to, and gave it to them.

      It was very much C code wrapped in a Java class, but honestly what else would you expect in that case?

      --
      I'm a signature virus. Please copy me to your signature so I can replicate.
    53. Re:Good habits by Raenex · · Score: 1

      50 megs of ram these days is trivial when the typical machine is running with multiple gigs. Also, you really don't need 50 megs for a simple app.

      What's really silly is that even a simple clock applet on Gnome takes like 10 megs, and that's written in C, but a bastardized C (GObject) because C is too low-level and people keep on reinventing some form of C++ on top of it.

      Laggy GUIs, yes, those are a problem, but for Java I blame Swing and the failure to use native widgets when possible. SWT has been an alternative option for a very long time. But even then, I believe the problem is overblown and a lot of it comes down to preconceptions, a lot of it harkening back to Java's early days back in the 90s.

    54. Re:Good habits by Tom · · Score: 1

      you can easily eat up all the memory or introduce a buffer overload vulnerability if you're not paying attention

      But that also means you can actually manage your memory.

      I once wrote a large-scale simulation in C, because the "intelligence" of memory management in every other language would've blown the memory I had available. In C I could make sure that it uses the precise amount of bytes I needed and not a single more (and single bytes matter if you take them times 16 million elements to simulate).

      --
      Assorted stuff I do sometimes: Lemuria.org
    55. Re:Good habits by epyT-R · · Score: 1

      yeah well I didn't buy 12GB so that my word processor can take 50-80MB instead of 5-8MB while offering little of value over the old version. using managed runtimes DOES incur a cost, just not one devs seem to care about: the user's time/hardware resources.

    56. Re:Good habits by Raenex · · Score: 1

      It's actually pretty ridiculous to complain about 50 megs when you've got 12 gigs. I just opened up a fresh copy of gedit and it is already sitting at 20 megs, then went to almost 30 megs when I opened up a 15k text file. Obviously it is wasteful, but I don't feel it even though I only run with a few gigs. And again, this is a Gnome "C" application. I can remember when having a whole meg for a text editor meant you blew the memory on your 640k PC. Times have changed.

    57. Re:Good habits by Anonymous Coward · · Score: 0

      Agh! Please stop spreading this myth.

      Yes, some "C guys" write better code than "Java guys". But I've seen first hand that many C guys can't really bother with the OO parts and suddenly after they've been in the project you have an entire C-section of your code somewhere where the C guys have just foregone all OO in the code base and coded their own little C corner (complete with implementations of algorithms/etc available in the Java standard library). Cleaning up a mess like that is extremely annoying.

      Good programmers that take care to write code as appropriate for the language that they're currently working in will produce better code than programmers who are "[Insert language here] guys". As a programmer you should always try to leverage the tools currently available to you, not get stuck in the "This is how you do it in language X so of course this is the optimal way to do it language Y" trap...

    58. Re:Good habits by TheRaven64 · · Score: 1

      No, the hate comes from using C where it's not the right tool for the job. C is a great language if you need all of the low-level control that it exposes. It is the best choice for code where performance is absolutely critical. It is the only sane choice for code where you need to have a very clear idea of exactly what the generated code will look like. It is a terrible language for application development.

      --
      I am TheRaven on Soylent News
    59. Re:Good habits by LizardKing · · Score: 1

      A "me too" on this one. One system I worked on had an emergency release that accidentally pulled in a bunch of new code from a junior developer. Shortly afterwards, the whole system ground to a halt and the DBA started to scream loudly since the DB server ran out of file descriptors ...

    60. Re:Good habits by lwriemen · · Score: 1

      The OP of this thread detailed a laundry list of flaws. His final quote should have been, "What doesn't kill you makes you stronger." Sure, you get used to C's limitations ("great power"[sic]) and get used to programming in it, but that doesn't make it easy. Constant vigilance against C's limitations means you are wasting a lot of time that could be applied to problem solving of the task at hand.

    61. Re:Good habits by ClayDowling · · Score: 1

      A shoddy developer will be a shoddy developer in any language. If they're putting proof of concept code into production, a different language isn't going to fix that problem. Trust me that large projects can be written in C, and can work quite well. I work on a large project where all of the heavy lifting is done in C, and there's a lot of it. The problems with the system are very rarely in the C code. It's usually in the interpreted languages where we get bit in the shorts.

    62. Re:Good habits by Anonymous Coward · · Score: 0

      Large projects in C don't make sense, huh? I will be sure to inform the Linux community, Microsoft's Windows division, Blizzard, EA, and all of the other major software vendors that their language of choice makes little sense.

    63. Re:Good habits by hackula · · Score: 1

      You can certainly cause memory leaks in C#. It happens pretty often with long running apps on the server side, since they have a lot longer to accumulate crud at runtime. Idk if the C guys would be any better at preventing these types of leaks than inexperienced C# people. Typically these are caused by mistakes such as not using the "using" blocks on IDisposable objects.

    64. Re:Good habits by hackula · · Score: 1

      Thank you. Do people really believe that you can just jump in with no knowledge of OOP and crank out highly structured and maintainable code? High level languages are about long term maintainability and complexity management. In C, this is achieved through methods that would seem primitive at best to anyone from a higher level background.

    65. Re:Good habits by Xiaran · · Score: 1

      Thankfully my guys code never made it to PROD. A good thing too as it was going to talk to the Notes mail servers that were seriously close to being at capacity... for an organisation of around 10,000 people :)

    66. Re:Good habits by Anonymous Coward · · Score: 0

      You young Whippersnapper! Why, when I learned C, casts weren't invented yet.
      The preprocessor was optional. Unions didn't exist, and structure member names
      had to be unique. You could jump to arrays of integers (oh, wait, you can still do
      that, but gcc requires a flag). To copy more than a word of memory required
      a loop, a function call, or multiple statements.

      Kids these days...

    67. Re:Good habits by Anonymous Coward · · Score: 0

      It forces programmers to actually look at what they're doing

      So is coding with a handgrenade tied to your forehead, one careless facepalm and Boom! Makes you really carefull what you're doing!
      But it won't improve your coding efficienty one bit, on the contrary. So unless your application *requires* low level control, a small footprint or elaborate performance tweaking you just don't bother with the overhead. Instead you let the langauge take care of it and focus on what matters: your application's logic flow.
      There's no miracle to it, time spent fixing memory management is time you don't code application logic, time spent learning low level management is time you don't spend learning how to translate requirements into logic.

      That being said, the best use I made of C was educational. It forced me to understand and interact with the low level building blocks of a computer. I'm glad I had it in the curriculum but I haven't had any real life opportunity where it was the best tool for the job.

    68. Re:Good habits by jmsp · · Score: 1

      Yes, I feel for the guys who may have been forced to write complicated GUI apps or similar exclusively in C. But it's not nearly a common case in all my years.

      OTOH, C IS the right tool for:

      - systems programming (linux kernel in my phone is great, slim and fast, Java Android "kernel" isn't)

      - libraries implementing algorithms efficiently

      - small unix-tool-like apps

      - embedded/small systems

      - many other cases where small and fast is paramount, but you don't want to write it in assembly and lose portability

      So, I think we agree C still has some uses where it is second to none.

      The point is that since nobody really (?) needs to use C for application development, all that hate we are talking about seems out of proportion.

    69. Re:Good habits by Anonymous Coward · · Score: 0

      It's only strangely designed for *you* because you don't understand hardware very well. In my previous experience with TI DSP boards, it's been one of the better brands out there.

    70. Re:Good habits by epyT-R · · Score: 1

      I meant that the increase in resource doesn't scale well with increases in functionality.. there's really no reason gedit should take 20MB..

    71. Re:Good habits by Anonymous Coward · · Score: 0

      Fair point, but you are essentially saying the Ferrari F1 team change tyres better than your local mechanic. Its probably true, but it's a false equivalence.

      There is a vast amount of software being written and waiting to be written. And there are a vast number of programmers writing this software. Sure, having 'c skills' probably makes you a *better* programmer, but if you are in the right job, you hopefully don't need to be too much better. There is an army of mid level coders who will never need to worry about memory management, for whom the convenience of Java (say) more than outweighs the gains of 'better c code'.

      Simpler languages allow shit programmers to write shit programs, but they also allow average programmers to write decent programs. I would suggest there is an improvement at the middle, even if the ends suffer a bit.

      Remember the bell curve and use your top 5% for the hard stuff, and the other 95% for the everyday stuff - done beats perfect!

  6. Who made that question? by Anonymous Coward · · Score: 4, Insightful

    A web developer?

    C is the the best tool around for low level programming. It allows very high levels of abstraction and it keeps you very close to your architecture's features.

    FORTH and C++ are used to the same means, but I do not hear much about other tools being used for this kind of development.

    1. Re:Who made that question? by TheSpoom · · Score: 2

      I'm a web developer and the question was equally stupid to me. Hell, I know OkCupid runs just about everything in C or C++ (or did, not sure about now), mostly as they do an insane amount of mathematical calculation and need it uber-optimized.

      --
      It's better to vote for what you want and not get it than to vote for what you don't want and get it.
      - E. Debs
    2. Re:Who made that question? by Misagon · · Score: 1

      Not just them. The biggest high-volume web sites have their performance-critical parts made in C or C++. As volume goes up, so does server load, and it starts to cost big money.

      One example is Facebook. They started out using PHP, but now they auto-translate PHP scripts to C++ for performance. They even built their own servers to save energy and they still pay in excess of one million dollars each month for electricity.

      In the past few weeks, I have been to several interviews for positions as a C++ backend web developer. I couldn't see many job ads for that five years ago.

      --
      "We mustn't be caught by surprise by our own advancing technology" -- Aldous Huxley
    3. Re:Who made that question? by bhcompy · · Score: 1

      Seriously. Wall Street's web platforms rely on ms and ns to beat others for trades. They sure as hell aren't handling this in PHP and ASP

    4. Re:Who made that question? by shutdown+-p+now · · Score: 1

      C is the the best tool around for low level programming. It allows very high levels of abstraction and it keeps you very close to your architecture's features.

      It is unfortunate, though, that today C is indeed the best tool for that, because it was not the best tool historically, and it does have quite a lot of warts. Starting with #include and declarator syntax. All of that could be fixed without detracting a single bit from it being "close to the metal" etc. But then if you did all that, you'd end up with Modula-2...

    5. Re:Who made that question? by Coryoth · · Score: 1

      FORTH and C++ are used to the same means, but I do not hear much about other tools being used for this kind of development.

      Actually I think Ada gets a lot of use for this sort of thing, particularly in the embedded realm. It has a whole host of "close to the metal" features, some better than C, and a whole lot more safety than C, even for "unsafe" features (such as strictly controlled pointers for direct memory addressing that are much safer than what C provides). Now that Ada2012 is out the language has continued to improve, with far more improvements and features than the meagre offerings of C11.

    6. Re:Who made that question? by gbjbaanb · · Score: 1

      another one is Microsoft - yup. Look at their Casablanca project for a hint of where they're going for cloud computing. They've realised just how much money non-native systems are costing them running all those servers.

    7. Re:Who made that question? by Darinbob · · Score: 1

      Ada is not too bad for this. It's just not very popular outside of a few circles. I think it beats out C++ in terms of straddling low level and higher level programming language concepts. I think it got a bad rap from the early standard.

    8. Re:Who made that question? by solidraven · · Score: 1

      People often forget Ada's main asset. It's brilliant at multi-threading and parallel execution. Very few languages are capable of what Ada can do with that.
      But it requires a certain mindset from the programmer that doesn't come naturally. I hated Ada until I had to start working with VHDL, being forced to think in parallel with a highly modular structure made things a lot easier. From that point on I finally understood why Ada is actually one of the best programming languages out there. It allows you to apply almost any programming methodology but prevents you from making bad design decisions. It also helps that it actively makes a difference between object values, methods and properties. C++, Java, Ruby, ... really aren't able to do that.

      And why C still gets used? Why replace something that does its job well. C can be a scalpel or a sledge hammer depending on what you want or need. Need to carefully modify certain parts of the memory, C is up for the job. Need to process a few gigabytes of data quickly, no problem. It's reliable, produces fast code, has good tool chains, it's well supported, and allows for quick coding (if the programmer knows what (s)he's doing). Another important fact is that you can combine it with assembly without painful constructions. In fact can't imagine writing low level abstraction code without using C. It's the perfect bridge between low and high level code.

    9. Re:Who made that question? by Deorus · · Score: 1

      It is unfortunate, though, that today C is indeed the best tool for that, because it was not the best tool historically, and it does have quite a lot of warts. Starting with #include and declarator syntax. All of that could be fixed without detracting a single bit from it being "close to the metal" etc. But then if you did all that, you'd end up with Modula-2...

      How do you fix #include without adding requirements to binary file formats? The metadata that goes in headers needs to be somewhere, the compiler can't just guess how your functions and data types (and templates in C++) are declared.

    10. Re:Who made that question? by shutdown+-p+now · · Score: 1

      Same way it's done everywhere else. Add keywords to indicate which members of the translation unit should be exported, and generate separate files containing only metadata from them. Those don't have to be binary - they can be plain text if desired, and they can even use regular C declaration syntax (but be restricted to declarations only) for backwards compatibility.

      The other thing would be replacing #include with something that'd remove the need for explicit header guards, like Obj-C #import.

    11. Re:Who made that question? by Deorus · · Score: 1

      Same way it's done everywhere else. Add keywords to indicate which members of the translation unit should be exported, and generate separate files containing only metadata from them. Those don't have to be binary - they can be plain text if desired, and they can even use regular C declaration syntax (but be restricted to declarations only) for backwards compatibility.

      You've just described header files.

      The other thing would be replacing #include with something that'd remove the need for explicit header guards, like Obj-C #import.

      Most compilers support #pragma once, a VC++ extension. Personally I've done macro-metaprogramming before and like to be able to recurse headers for when i need black magic in C (C++ has templates for that).

    12. Re:Who made that question? by shutdown+-p+now · · Score: 1

      You've just described header files.

      Not really. For one thing, header files are not automatically generated. One could write a tool to do that, but, since standard C does not have any way to indicate what types to export, it would have to be driven by "magic comments" or something like that. For another, header files still permit code in them, and have other problems associated with textual inclusion (such as pollution by essentially "private" macros).

      Most compilers support #pragma once, a VC++ extension. Personally I've done macro-metaprogramming before and like to be able to recurse headers for when i need black magic in C (C++ has templates for that).

      Textual inclusion - including recursion - is occasionally useful, but it definitely shouldn't be the standard way to import the interface of another module, for reasons outlined above. Ideally, I'd want both.

    13. Re:Who made that question? by Deorus · · Score: 1

      Not really. For one thing, header files are not automatically generated. One could write a tool to do that, but, since standard C does not have any way to indicate what types to export, it would have to be driven by "magic comments" or something like that. For another, header files still permit code in them, and have other problems associated with textual inclusion (such as pollution by essentially "private" macros).

      First, it's easy to guess what types to export -- you need to export all the types that your non-static functions and variables use either as return values or arguments. Secon, nobody in their right mind puts non-inline and non-generic code in header files. Doing so would cause link-time collisions, so that's a non-existing issue. Third, pollution is a problem that you would continue to have with or without headers since people would continue to forget to make their stuff static. Furthermore, without headers you would actually have no way to propagate macros, and this is a real issue to me.

    14. Re:Who made that question? by TheRaven64 · · Score: 1

      The problem with header files is that they don't exist in the language. They are purely convention. The preprocessor will insert ANY file that you specify with #include, whether it contains code or declarations. The convention is that header files have a .h extension and only contain declarations, but this is not enforced. Over time, the size of header files grew and it's not uncommon for each compilation unit to contain several megabytes of text, which has to be tokenised and parsed with every compiler invocation, which is why precompiled headers are popular now. Unfortunately, header file include order actually matters and so precompiled headers are a problem - they will be silently ignored in a lot of cases because a change in the include order means that they are invalid. Because C compilers traditionally lacked link-time optimisation, it's also common to include a lot of inline functions in header files. In a modern compiler and language design, these would be compiled to an intermediate representation once and then inlined during the linking phase. In C, the compiler must parse them for every compilation unit. This is even worse for C++, where the compiler must also generate code for them and rely on the linker to remove the duplicates.

      --
      I am TheRaven on Soylent News
  7. Control by Dan+East · · Score: 5, Insightful

    C offers control. If you can't handle having that much control (over memory, how the CPU acts on that memory, etc) then your software will have many problems and you will hate C.

    --
    Better known as 318230.
    1. Re:Control by jythie · · Score: 5, Insightful

      Not just control, but predictability. C does exactly what you tell it to do and you can see what it is doing more easily then other languages. You can tell C++ to do 'X', but it might slip in a 'Y' and 'Z' without telling you.

    2. Re:Control by Anonymous Coward · · Score: 1

      Ding ding. This is the correct answer.

      This is exactly the same reason that air traffic control still use software running on computers made in the late 90s. Why? Because they know it's reliable and will do exactly what they want. Businesses don't necessarily care about fast, nor do they care about cheap. These are bonuses. What they want is something that requires minimal maintenance and will be foolproof for years.

    3. Re:Control by Anonymous Coward · · Score: 0

      a=a++;

      I rest my case.

    4. Re:Control by Anonymous Coward · · Score: 2, Insightful

      That's BS. C++ isn't going to "slip anything in." Its standard has pretty much the same rules of predictability that C has.

    5. Re:Control by rgbrenner · · Score: 1

      what is confusing about that?

    6. Re:Control by Raenex · · Score: 2

      C does exactly what you tell it to do and you can see what it is doing more easily then other languages.

      Thanks for the laugh. C is absolutely full of either undefined behavior or implementation defined behavior, by design. On top of that, it has this mantra of "trust the programmer", which in reality means don't help the programmer out, so they often end up in undefined territory by making simple mistakes.

    7. Re:Control by Thiez · · Score: 3, Interesting

      C, predictable? Would you mind taking this http://blog.regehr.org/archives/721 quiz? It's about the predictability of integers in C.

    8. Re:Control by ZorroXXX · · Score: 1

      "a = a++" is undefined behaviour according to the standard (modifying a variable several times between two sequence points).

      --
      When you are sure of something, you probably are wrong (search for "Unskilled and Unaware of It").
    9. Re:Control by Anonymous Coward · · Score: 0

      I bet the parent is talking about how operator overloading or deep class inheritance can make source code which looks safe and simple have unexpected results to the person reading it (and therefore somebody untrained with code x goes in to fix something and breaks it even more).

    10. Re:Control by betterunixthanunix · · Score: 1

      If you can't handle having that much control (over memory, how the CPU acts on that memory, etc) then your software will have many problems

      Really? Sometimes, I am more worried about getting my logic right than about managing pointers. When I am looking through my code and trying to figure out why the results were not what I expected, I do not want to waste my time trying to decide if the problem was my algorithm or some dangling pointer somewhere. Sometimes, it is nice to know that the problem is with the algorithm and not just that a variable was uninitialized.

      Yes, sometimes you need low-level control. I would venture a guess that the bulk of the code in use today does not fall into that category.

      --
      Palm trees and 8
    11. Re:Control by betterunixthanunix · · Score: 1

      C does exactly what you tell it to do

      Assuming you even know what you are telling it to do:

      int i = 0;
      int x = i++ * i++;

      char * s = "hello, world!";
      s[0] = 'H';

      int i = 0;
      printf("%d %d %d\n", i++, i++, i++);

      ...and so forth. These, of course, are just toy examples that nobody should encounter in their code, but there an endless number of ways to accidentally write a complicated version of one of these.

      --
      Palm trees and 8
    12. Re:Control by Anonymous Coward · · Score: 0

      Ding ding. Wrong.

      I'm working for the German Air Traffic Control (DFS) in the SW department. All software developed there (Phoenix: http://en.wikipedia.org/wiki/Phoenix_%28ATC%29 ) is written in C++ (using Qt) and runs on Suse Linux and HP servers.

      Aside from that: templates are far more predictable than Macros.

    13. Re:Control by jythie · · Score: 1

      That is indeed my thought. Operator overloading and vtables are the boogie men that I found made C++ in embedded enviroments difficult. You never knew what that '+' was actually going to do, what functions it might spawn off and call instead of preforming the '+' operation, or how big a structure physically was going to be.

      As someone else pointed out, macros are their own problem, but templates and operator overloading not only made the problem worse, but they they are taught as heavily encouraged (where macros were generally something to avoid, or if you are going to use them have them in upper case).

    14. Re:Control by jythie · · Score: 1

      *shrug* at least you are only dealing with the issues in the C implementation itself. With C++ not only do you have all the issues of C, you have whatever the upstream programmers overloaded on any specific operation for any specific object.

    15. Re:Control by rgbrenner · · Score: 1

      right you are

    16. Re:Control by Thiez · · Score: 1

      I'll take that as a "I took the quiz but didn't get a perfect score" ;-)

      C has so much undefined behaviour it's not even funny. Of course in some instances it's nice because it allows more aggressive optimization by the compiler, but most of the time it just makes it easier to shoot yourself in the foot.

    17. Re:Control by busyqth · · Score: 1

      That's German ATC, GP is talking about *American* ATC.
      You know, the guys who were running vacuum tube computers up into the 80s.

      Don't give us any of that Linux/Qt crap, you crazy Kraut!
      You'll have to pry our APL and ADA out of our cold, dead hands!

    18. Re:Control by ADRA · · Score: 2

      C is the manual transmission of cars, its a lot harder to operate, but you have a lot more control of how it drives. More managed languages are the automatic transmission. For 99% of the time, it'll get you to where you're going just fine, but will waste a little more gas to do it. Standards are more efficient and auto's are more simple.

      To further expand the analogy, the new world order of standard transmission is to move into dual-clutch manuals, where you can still twist the knobs if you really want to, but you don't need to; everything runs automatically behind the scenes. Now to put this into a programming language paradigm, its something like making the C#/Java runtime's of the world so efficient that they're (pre?) runtime optimizers become so efficient at optimizing the codepaths that they produce better results than a typical C output. The runtimes are surely not there yet (for most cases), but in 20-30 years, I doubt there will be many pure C developers left just as there are almost non-existant need for assemby programmers in today's market. Jas in cars, the dual-clutch systems will become so cheap and so convenient that you won't find pure manuals in all but the most specific niche markets in well, maybe the same 20 years.

      --
      Bye!
    19. Re:Control by Anonymous Coward · · Score: 0

      In C, I know exactly what "cin >> foo" does just by knowing the types of cin and foo. In C++, I have no idea what "cin >> foo" translates to, let alone something even slightly more complicated like "cin >> ws >> foo". It's easy to reason about "x = y + z" in C, but in C++ you have no idea how many functions are going to be called, how much memory will be allocated, or how much stack space will be used.

      Of course, the compiler can obviously figure it out based on deterministic rules, but you can't know unless you know everything the compiler knows. And since the compiler only knows because it has processed thousands and thousands of lines of header files, it's unreasonable for a human to actually figure out.

      dom

    20. Re:Control by loufoque · · Score: 1

      Does this BS stand for bullshit or Bjarne Stroustrup?

    21. Re:Control by Anonymous Coward · · Score: 0

      What do you think happens when you do the following, then?

      class A
      {
      public:
              A() : _foo(allocateFoo()) {}

      private:
              unsigned short *_foo; // other members omitted for clarity
      };

      void doWork(A someA) { /* ... */ }

      A myA;
      doWork(myA);

      There is a subtle, but potentially serious issue with this code. What C++ has "slipped in" probably isn't apparent to people who haven't spent time writing C++ and getting used to its braindamages.

    22. Re:Control by Darinbob · · Score: 1

      Yes if you understand all of the rules and you pay attention to each and every word you program. If you do something like "use(a)" then you have to worry about overloading possibly, whether a has a copy constructor, and so forth. In C it will do one thing only.

    23. Re:Control by Khashishi · · Score: 2

      Ah, but this is an advantage of c. Things are left undefined because defining them would impose a performance penalty in hardware implementation.

    24. Re:Control by Teckla · · Score: 1

      Not just control, but predictability. C does exactly what you tell it to do and you can see what it is doing more easily then other languages.

      C? Predictable?! I suppose you've memorized C's 250+ implementation defined and undefined behaviors?

      Oh, unless you meant predictably unpredictable. Unless you're a superhuman programmer and can avoid the myriad minefields in the language.

    25. Re:Control by Anonymous Coward · · Score: 0

      I think what they mean is object oriented code encourages overloading and polymorphism, which is great as an ideal, but also can cause confusion in real life.

      It really comes down to the programmer(s) knowing what they're doing. C++ just gives you a bigger gun to blow off your foot if you don't know what you're doing.

    26. Re:Control by Anonymous Coward · · Score: 0

      There is nothing "subtle" nor "potentially serious" there, assuming allocateFoo() does what its name implies. Instead, the problems are definitely serious and obvious to any competent C++ programmer.

      This is just "C++ 101": the definition of class A lacks appropriate definitions of a copy constructor, destructor, and assignment operator. To resolve it, simply define the missing member functions. Alternatively, before C++11, declare the missing copy ctor without a definition to provoke a link-time error, or in C++11, use the delete keyword in the copy ctor declaration to cause a compile-time error; the same alternatives apply for the missing assignment operator, though the relevant problems are not illustrated in your example. Regardless, a proper destructor is still needed. If the class is defined in some closed source library, petition the vendor to fix it, or find a replacement that wasn't written by novices; if those options aren't available, enclose class A in a safe wrapper class.

      Code like your example comes from new (or bad) C++ programmers. Anyone who understands the material covered by Koenig & Moo's Accelerated C++ (a really small, easy book) would see the obvious problems with class A right away.

      - T

    27. Re:Control by FormOfActionBanana · · Score: 1
      --
      Take off every 'sig' !!
    28. Re:Control by godrik · · Score: 1

      That's it. It is in my opinion, the ONLY advantage of C over C++. There is no ambiguity EVER on what an operation mean. There is no weird boxing, type-cast, hidden function calls.

      Don't get me wrong, I love C++. But C is SO MUCH easier to understand becasue each operation does exactly what it says. It might not be very expressive, but it is never ambiguous.

    29. Re:Control by gl4ss · · Score: 1

      heh, had to try the last one, though that you could encounter in all languages that have ++ ?

      int i=0;
      System.out.println(" "+i+++" "+i+++" "+i++); makes a little more saner output though than the c compiler I tried(though I guess it's a matter of taste and reading direction).

      --
      world was created 5 seconds before this post as it is.
    30. Re:Control by Anonymous Coward · · Score: 0

      C has a lot of "undefined" behavior because it is a real language just like English or maths you can write, or say something that isn't possible, doesn't make sense or is just stupid. Only a few questions on that quiz seem inconsistent or strange like the x + 1 + 1 versus 1 + 1 + x but even then you are doing something you shouldn't be, at least that isn't the only thing you should be doing when you calculate numbers you have to still understand the limits of the domain you can handle and if not handle it.

      In say C# if you overflow an integer it throws an exception and your program dies if you don't manually handle the case or catch and ignore the exception, while in C it doesn't care that you are too stupid to be coding and isn't going to baby sit you. If you overflow something you might come back out the other side of the universe or you might step on some other memory. It's your job to not cast things in a retarded way and check your own bounds and throw your own exceptions. Personally I prefer being able to choose how a system should operate and have the freedom to shoot my foot off because there are plenty of tools and libraries available that allow you to have the best of both worlds.

      That said I hardly program in C but when I do the program deserved it.

    31. Re:Control by Anonymous Coward · · Score: 0

      Can I skip the expressions I've never used? If so, I got a perfect score.

    32. Re:Control by Anonymous Coward · · Score: 0

      Nope. Just the ones I use.

    33. Re:Control by Anonymous Coward · · Score: 0

      Maybe when the quiz is corrected it'll give me 100%. Some of the questions, especially those involving shifts of signed int are assuming an incorrect size for int. Also, the question about signed and unsigned char max needs a correct answer that can be selected. :)

      Not exactly hard to know the precedence rules, the type promotion rules, and the behaviour on overflow for integers.

      Admittedly, it could be simpler but it's not impossibly hard.

    34. Re:Control by GrahamCox · · Score: 1

      C is the manual transmission of cars, its a lot harder to operate, but you have a lot more control of how it drives.

      Bad car analogy alert! The problem you're overlooking is that a manual (or auto) transmission is already a band-aid for a much more fundamental problem: the fact that an IC engine is an unsuitable powerplant for an automobile. All those gears and clutches are there to workaround all of its various deficiencies. Making them manually operable is a further admission that the workarounds themselves are only partial solutions - they need some hand-holding for them to get their job done reasonably well.

      I'm not sure where that leaves C, but for efficiently programming a bare board with only 32K RAM it's hard to beat.

    35. Re:Control by cerberusti · · Score: 1

      The C standard defines many things explicitly that other languages do not. The minefield exists in all languages with more than one implementation, it is just that in C you get a map with known mine locations, and areas which you should probably check for mines before you go walking there.

      C compilers are generally by far the most stable, as the operating system is also written in C. If the system C compiler contains major bugs... chances are that the operating system is very unstable as well.

      --
      I'm a signature virus. Please copy me to your signature so I can replicate.
    36. Re:Control by betterunixthanunix · · Score: 1
      Actually, you should have tried the last one with several compilers and several architectures (yes, GCC will produce some different on x86 than PowerPC). The point of the last one is that the order in which arguments to a function are evaluated is undefined in C, so if you have arguments that have side effects (e.g. function calls that modify global variables), the behavior of your program is undefined:

      http://www.eetimes.com/discussion/programming-pointers/4023961/Evaluating-Function-Arguments

      This can cause all sorts of issues:

      int i = 0;
      int f(){i++; if(i == 1) return 5; else return 6;}

      int g() {i++; return 6;}

      float h(int i, int j){return 1/(i-j);}

      int main()
      {
      h(f(),g());
      return 0;
      }

      The code in main() looks innocent at first -- but it has undefined behavior. This is something that is easy to accidentally write, too; you could call any number of standard library functions that update some global state. The C standard, section 6.5.2.2, says the following about this sort of thing:

      The order of evaluation of the function designator, the actual arguments, and subexpressions within the actual arguments is unspecified, but there is a sequence point before the actual call.

      Things are even worse in C++; you might not even realize that you have function calls in your argument list in C++ e.g. you might be calling a copy constructor for a smart pointer.

      --
      Palm trees and 8
    37. Re:Control by Branciforte · · Score: 1

      No. Look at the operator. Not look at what it is operating on. Is it operating on primitive types? Then you know what it does. Is it operating on objects? Then you know it is just a convenient syntax for a well-known function name (e.g. "operator+).

      Why do you people find this so hard to comprehend?

    38. Re:Control by Anonymous Coward · · Score: 0

      All that stuff is very predictable, just because you don't know the rules doesn't mean it is not predictable. Obviously every platform works differently that's the price you pay for having an extremely low-level control over the machine.

    39. Re:Control by Anonymous Coward · · Score: 0

      That's a stupid argument. Apply your argument to C++, and now the same quiz grows to 100x the size.

      Sure there are various pitfalls you have to be aware of in C, but C++ retains all of those and lumps a hundred times more that the programmer has to be aware of.

    40. Re:Control by Teckla · · Score: 1

      The C standard defines many things explicitly that other languages do not. The minefield exists in all languages with more than one implementation, it is just that in C you get a map with known mine locations, and areas which you should probably check for mines before you go walking there.

      I disagree. C goes out of its way to have bunches of implementation defined behaviors so that it's easier to port or write C compilers for unknown or weird architectures. This is great for the compiler implementer, but puts an extra burden on the software developer to be aware of all those implementation defined minefields. All those implementation defined behaviors also makes it easier to have a C compiler generate extremely efficient code for your target architecture, so it's a trade-off.

      That's all a long-winded way to say that C is complex in some ways (you really need to keep a handle on all those undefined and implementation defined behaviors), but also very powerful (it is those implementation defined behaviors which allows for the very efficient code generation).

      C compilers are generally by far the most stable, as the operating system is also written in C. If the system C compiler contains major bugs... chances are that the operating system is very unstable as well.

      I agree that C compilers are generally very reliable. In 25+ years of C programming, I've only found a few actual C compiler bugs. And, come to think of it, they may not have been C compiler bugs, but rather, bugs in some library routines, and not even in the standard library itself.

    41. Re:Control by Anonymous Coward · · Score: 0

      This quiz is not so much about predictability, but rather exposing the dynamic nature of the language, and it's usage. The results are very predictable, if you understand the usage.

      The problem being (and as most people who favor C will point out), C requires that you know what you are doing. It is the difference between:
      Screwing in a light bulb (HTML/PHP)
      Replacing a Ballast: (.Net/Java/Objective-C)
      Making a home-made battery to power your light bulb: (C++)
      Building a light bulb and battery from scratch: (C/Asm)
      Analyzing and cataloging the components necessary for creating light (mySQL/PostGre/MSSQL/...)
      Analyzing the chemical make-up and reactions necessary for creating light: (Fortran)

      Under many situations, you don't want to work with a different tool, but, different tools do offer ways of doing different tasks in a more accurate and clean way, vs a faster and less articulated way.

      You need to understand how much time you need to focus on the development. Your knowledge of the tools you use. The interoperability of the tools. And ideally, you can either focus on one tool, or use the appropriate tool for the appropriate component.

      Shoe-horning any tool into every situation is always going to cause problems. And assuming that one language is worse than another simply because it appears overly complex, or overly simplified is a dangerous bias, and can (and has under many situations) lead to failed projects.

      C is a great language, and will continue. Not because I believe it will, not because it is the best language. But because it provides the best ability to deal with specific, and known situations. And as long as that's true, it will continue.

    42. Re:Control by gl4ss · · Score: 1

      wow, that sucks a lot, seems like something like that would have been easy to standardize.

      personally I dislike operator overloading too, for the simple reason that it's harder to see straight away what's going to happen(and I don't think .add(whattoadd) is too cumbersome. blaa+="blaa" particularly, when the end result is that blaa is going to be an entirely new object..).

      --
      world was created 5 seconds before this post as it is.
  8. The portable assembler by heson · · Score: 5, Insightful

    Close to the metal but still not specific to any machine if you do not need to. Easy to understand exactly what machinecode the compiler will produce.

    1. Re:The portable assembler by Anonymous Coward · · Score: 0

      Exactly. There are many companies I know of that still use C specifically because of this. These are companies that produce software for avionics, medical, etc. where hard real time performance is required and thorough understanding of all the execution paths of the code is required for certification of the product.

  9. Small, fast,simple, support by Anonymous Coward · · Score: 0

    While it's true plain C is old and (when not used properly) unsafe, it is also very fast, cross-platform and there have been thousands of libraries made to work with it. Plus, for low-level stuff, it's still one of the better options. Almost all languages have good and bad points, C's good points obviously outweigh the bad or it wouldn't be used for so many projects.

  10. Not a "Nanny State" language... by Anonymous Coward · · Score: 2

    You have to know what you are doing when you C and you can do anything...

  11. Sesame Street already covered this by Zephyn · · Score: 5, Funny

    It's for cookie.

    That's good enough for me.

    1. Re:Sesame Street already covered this by AntEater · · Score: 1

      Heartless and Evil, that's what you are. I've gone almost 30 years since I last had that song stuck in my head. Thanks!

      --
      Alex, I'll take keybindings not used by Emacs for $400....
  12. a long enough rope... by Anonymous Coward · · Score: 0

    C gives you the rope to hang yourself at a lower level - no strong typing, poor tools for abstraction . .Net, Java et al will hang you with their class explosion, athough you might enjoy the higher view before the rope tightens.. It depends on who's writing and for what purpose, not the language itself.aka - No pointers here, keep moving.

  13. Re:news for n00bs by Anonymous Coward · · Score: 0

    stuff that everybody knows

  14. Shorthand for Assembler by codefool · · Score: 5, Interesting

    The power of C is - and always has been - that it is a shorthand for assembly. It compiles very small and runs very fast, making it ideal for embedded systems.

    --
    "Stop whining!" - Arnold, as Mr. Kimble
    1. Re:Shorthand for Assembler by Thiez · · Score: 1

      If only it compiled at the same speed as assembly...

    2. Re:Shorthand for Assembler by Coryoth · · Score: 1

      The power of C is - and always has been - that it is a shorthand for assembly.

      Except it really isn't -- at least not for a great many modern processors. Compile C on x86-64 for a project of any decent size (as opposed to simple code snippets) and witness all sorts of subtley different things get produced depending on exactly what you've written; the optimizer for the compiler, combined with SSE instructions etc. produce all sots of things that are a long way from a direct translation of the C you wrote. That is, of course, good because your code runs much faster, but it makes it a long way from a short hand for assembly.

      It compiles very small and runs very fast, making it ideal for embedded systems.

      It compiles small and runs fast often precisely because it is not a short hand for assembler -- the compiler does all sorts of fun and interesting things. There are lots of other languages that compile small and run fast (Ada, Eiffel, BitC, SML, Pascal, Modula, Fortran) and many of them survive well to this day with many updates and new features (honestly, look at the latest Fortran specs; it's now an OO language with generics and all manner of other stuff if you want). Some, such as Ada are better suited for embedded development than C. What C has is an early foothold and being "good enough" (though just barely good enough). It's not going anywhere soon, but that's not exactly a good thing.

      P.S. For reference I do almost all my programming in C and dialects thereof.

    3. Re:Shorthand for Assembler by codefool · · Score: 1

      I agree with your comments. When I started with the Lifeboat compiler "back in the day" I could visualize the assembly that would be generated with the C code being written. Reading from K&R, it's clear that constructs such as switch(), prefix/postfix increments and the like, the register modifer, etc. were all there to make it easier to generate straight-line assembly in a friendlier syntax (I seem to recall that it would, in fact, generate an assembly source listing if requested.). Even the #asm shows the intimacy between the two. To your points, modern compilers "interpreting" C source into something that is much smaller/faster may get a Good Thing in the long run, but I miss the days when I could just code and know exactly what the compiler would produce. I also remember those times I had to write subroutines in assembler because the compiler refused to produce what I wanted. Sometimes the optimizer is wrong.

      --
      "Stop whining!" - Arnold, as Mr. Kimble
  15. Think of it as standardized assembly programming by localman57 · · Score: 5, Insightful

    C is going to stay around for a long time in embedded systems. In this environment many microcontrollers still have 4k or less of RAM, and cost less than a postage stamp. In these systems there is virtually no abstraction. You write directly to hardware registers, and typically don't use any dynamically allocated memory. You use C because, assuming you understand the instruciton set, you can pretty much predict what assembly instructions it's going to generate and create very efficient code, without the hassle of writing assembly. Aditionally, your code is portable for unit testing or, to a lesser degree, other microcontrollers. This allows you to write a program that will run in 3.2 k of ram, rather than 4k, which allows a manufacturer to save 4 cents on the microcontroller they pick. This saves you $40,000 when you're making a million of something.

  16. Because by Anonymous Coward · · Score: 1

    Its a way to tell a machine what you want it to do that ends up doing exactly what you expected in the most efficient way. C++ too, sometimes. Java, never.

  17. Letting the opinions of others decide for you by Anonymous Coward · · Score: 0

    Is not in your best interest. Or are you just a troll fishing for page views?

  18. Where'd the Unix go? by burdickjp · · Score: 4, Interesting

    It's not dead because all of your VMs and interpreters have to interact with SOMETHING, and that SOMETHING has to be written in a low-level language. I strongly believe in using only the lowest-level language necessary for the job, but for OS development that's C.

  19. Simple. by Short+Circuit · · Score: 5, Insightful

    Tons of people love to have something to hate. It might be because they don't like something about it...but I think it's mostly because people like to set up communities held together by rhetoric against a tool or technology perceived and portrayed as an enemy.

    "C++ sucks. We are at war with C++. We have always been at war with C++.[1]"

    Swap out "C++" for whatever language you like.

    Certainly there are going to be cases and scenarios where C is preferable over C++, where C++ is preferable over C, or where Brainfuck is preferable over either. Use the right tool for the right job,[2] and the right tool is whichever allows you to most effectively achieve your goals.

    [1] Or, at least since its inception. Or since [insert arbitrary date here].[3]
    [2] For whoever asks "what's the right job for Brainfuck?" ... just wait. Someone will eventually come along and get modded +2 Funny when they reply to you.
    [3] I see what you'll do there, Mr. Connor.

    1. Re:Simple. by Bill_the_Engineer · · Score: 1

      Repeat after me: C++ is not equal to C

      --
      These comments are my own and do not necessarily reflect the views or opinions of my employer or colleagues...
    2. Re:Simple. by Bill_the_Engineer · · Score: 1
      Disregard. I found your

      Certainly there are going to be cases and scenarios where C is preferable over C++, where C++ is preferable over C, ...

      --
      These comments are my own and do not necessarily reflect the views or opinions of my employer or colleagues...
    3. Re:Simple. by localman57 · · Score: 2

      Repeat after me: C++ is not equal to C

      Wait. Did you mean equal "=", or equal "==" ?

    4. Re:Simple. by Anonymous Coward · · Score: 0

      assert(C == C++);

    5. Re:Simple. by Anonymous Coward · · Score: 0

      Repeat after me: C++ is not equal to C

      Wait. Did you mean equal "=", or equal "==" ?

      I'm a little rusty, but I'm pretty sure "c++ = c" would give you a syntax error (unlike c = c++). "c++ == c" I believe will increment c, then compare it to itself, and so return true. So actually, c++ == c is true.

    6. Re:Simple. by serviscope_minor · · Score: 1

      For whoever asks "what's the right job for Brainfuck?" ... just wait. Someone will eventually come along and get modded +2 Funny when they reply to you.

      Brainfuck is the right tool for the job if the job is to be a simple a language for which one can create the world's smallest ELF capable compiler.

      --
      SJW n. One who posts facts.
    7. Re:Simple. by jpvlsmv · · Score: 1

      C++ is equal to C in the context of the current expression (atom).

      Or don't you understand the difference between preincrement and postincrement?

      The fact that ++i and i++ can be interchanged in many contexts is an optimizer feature.

      int main(void) { int C=11; if (C==C++) printf("They are equal\n"); }

      --Joe

    8. Re:Simple. by Short+Circuit · · Score: 2

      assert(C == C++);

      Beautiful. Someone needs to prep an April Fools joke for next year for renaming C++ to ++C.

    9. Re:Simple. by Anonymous Coward · · Score: 0

      Of course it isn't.

      Nigel Tufnel: Well, it's one more, isn't it? It's not ten. You see, most blokes, you know, will be programming at ten. You're on ten here, all the way up, all the way up, all the way up, you're on ten on your computer. Where can you go from there? Where?
      Marty DiBergi: I don't know.
      Nigel Tufnel: Nowhere. Exactly. What we do is, if we need that extra push over the cliff, you know what we do?
      Marty DiBergi: Put it up to eleven.
      Nigel Tufnel: Eleven. Exactly. One more.

    10. Re:Simple. by Anonymous Coward · · Score: 0

      Disregard. I found your

      Certainly there are going to be cases and scenarios where C is preferable over C++, where C++ is preferable over C, ...

      No, no, the smug, condescending "Repeat after me" bit, like you were talking to a child or a mental retard, makes your statement well worth regarding, especially given what was stated in the parent post that you clearly ignored. Thank $deity Slashdot doesn't let you chicken out and change your previous posts!

      NOTE: Yes, I DID mean that as a Perl-style scalar in an article that's basically a standard-issue programming language hatefest. That's right, I went there. Come at me, bro.

    11. Re:Simple. by Bill_the_Engineer · · Score: 1

      Neither!

      "=" is an assignment and "==" only tests if the L-value are the same.

      We should use !cpp.equal(c) or !equal(C,CPP)

      ;)

      --
      These comments are my own and do not necessarily reflect the views or opinions of my employer or colleagues...
    12. Re:Simple. by Bill_the_Engineer · · Score: 1

      NOTE: Yes, I DID mean that as a Perl-style scalar in an article that's basically a standard-issue programming language hatefest. That's right, I went there. Come at me, bro.

      Using perl is punishment enough for you.

      --
      These comments are my own and do not necessarily reflect the views or opinions of my employer or colleagues...
    13. Re:Simple. by Carl+Drougge · · Score: 1

      It's undefined in either case, because == is not a sequence point. (That is, the right side will yield the value C had before this statement, but the left side might not. Probably anyway, I'm not going to look it up.)

    14. Re:Simple. by c++0xFF · · Score: 1

      Let's clean up some of that rust, shall we?

      The result of "c++ = c" depends on the type of c and whether the return value of the increment operator returns a value that is assignable from a value of the type of c. However, if c is an int or other primitive type, "c++ = c" gives a syntax error as c++ is not an l-value.

      Operator overloading ... wonderful if used right, but you can certainly do weird stuff with it, too.

      In the case of "c++ == c" ... I believe the standard specifies this as undefined behavior, since you're incrementing and reading the value of c in the same statement, and I don't believe there's a sequence point to make the statement valid.

    15. Re:Simple. by dkf · · Score: 1

      For whoever asks "what's the right job for Brainfuck?" ... just wait. Someone will eventually come along and get modded +2 Funny when they reply to you.

      Brainfuck is the right tool for the job if the job is to be a simple a language for which one can create the world's smallest ELF capable compiler.

      The main problem with Brainfuck as a language is the severe lack of system calls available, and has no foreign-function interface either (which could be used to integrate an assembler snippet that did system calls). Without the system calls, you can't be a practical language, and will always be stuck being a toy.

      --
      "Little does he know, but there is no 'I' in 'Idiot'!"
    16. Re:Simple. by humanrev · · Score: 1

      Tons of people love to have something to hate. It might be because they don't like something about it...but I think it's mostly because people like to set up communities held together by rhetoric against a tool or technology perceived and portrayed as an enemy.

      Indeed. Explains a lot of the hate towards Microsoft I see from the Linux community. Not that all of that hate is unjustified (Microsoft does provide a lot of ammo for it at times), but since the bulk of the hate seems to come mainly from zealot Linux users and generally not from any other group, your explanation is more accurate than you think.

      --
      Most people on Slashdot are fucking idiots.
  20. Re:because - by Anonymous Coward · · Score: 0

    static char const post[] = "first";

    I bet many don't know the difference between :

    const char *foo; and char const *foo;...

    CAPTCHA = golden (Thank you!)

  21. Aniquted, clunky and unsafe by sl4shd0rk · · Score: 0

    C is not python, nor is it PHP. Yes, C is quite mature and there are several aspects of it which share a certain amount of tedium but some things can only be achieved with a certain amount of toil. As far as being unsafe, well, that's relative to the programmer. Be glad your not asked to write in Assembly.

    --
    Join the Slashcott! Feb 10 thru Feb 17!
  22. simplicity by roman_mir · · Score: 4, Insightful

    C is a very simple language and yet it allows operating memory directly in a way similar to assembler. C is portable (well, it can be compiled for different platforms), I rather enjoyed the language a while back, but since about 98 I use Java for most of big development and I am pretty sure that if I had to do everything in C that I did in Java, it would have taken me much more time.

    C is nice in another way - it allows you and in some sense it forces you to understand the machine in a more intimate way, you end up using parts of the machine, registers, memory addresses, you are more physically connected to the hardware. Java is a high level abstraction, but then again, to write so much logic, it is just better to do it at higher level, where you don't have to think about the machine.

    C is great tool to control the machine, Java is a great tool to build business applications (I am mostly talking about back end, but sometimes front end too).

    So I like C, I used to code in it a lot, but I just to use it nowadays. What's to love about it? Applications written in it can be closely integrated into the specific OS, you can really use the underlying architecture, talk to the CPU but also the GPU (CUDA), if I wanted to use the GPU from a Java application, I'd probably end up compiling some C code and a JNI bridge to it.

    C teaches you to think about the machine, I think it gives an important understanding and it's faster to develop in than in Assembler.

    1. Re:simplicity by Anonymous Coward · · Score: 0

      My point of view is probably too offensive for most people but I'm just tired to see these poorly designed softwares (developed by this kind of people) :
      "If you don't like C, it means that you don't want to understand how machines work, then don't EVER touch a machine again and spare the world of any sh*t you could possibly imagine..."

    2. Re:simplicity by roman_mir · · Score: 1

      Well, I didn't even say that, but try and argue that extra understanding of what is going on below your abstracted point of view hurts you. I can easily argue that understanding the machine makes you a better developer, even if this understanding is just at the level of OS itself. Knowing the limitations of the machine is important for example, if you are threading your high level app, you better know something about the context switching that is taking place just below you, you may want to learn something about the scheduling procedure too. If you abstract everything, you will still be able to write a business app, but you won't use the available memory efficiently.

      Your app may talk to a database, you better know something about the network interfaces, your app may read and write files, you better know how to be efficient about it even at your high level, you better be familiar with the file system and its constraints (and specifications).

      You better know what 'headless' means and how your OS handles it if you are trying to do some graphics processing on the server.

      Should you know what sockets are at a level lower than your abstract language you think? Should you know how your OS handles them, what if they leak, what happens, do you know? If your file handles leak? Do you understand what socket handles are vs file handles? How about descriptors, do you know the difference, is there a difference?

      If you don't know your hardware, how do you know to optimise wear and tear on the drives? What you are mixing and matching HDs and SSDs? If you are using a database that writes logs ahead and commits once they logs are written, and if you use SSDs and HDs, what's a better strategy to place the logs? How about archiving, what about recovery?

      Do you believe you shouldn't ever have to think about the PHYSICAL LIMITATIONS of what you are working with?

    3. Re:simplicity by Anonymous Coward · · Score: 0

      I'd add to your list that it forces you to *really* understand data structures and the algorithms that operate on them. Data structures and algorithms are *the* fundamental elements of computer science. A high-level programmer only has an inkling about these things. Their language gives them hashmaps and arrays, and they try not to iterate them with n^3 loops or something. When you actually have to *implement* your own custom hashes and lookup algorithms, and have the flexibility to decide to use something else instead (is a binary tree better? maybe a doubly-linked-list with a hash-based LRU cache in front of it is better? Or a 4-heap?) and write the algorithms that operate on them, you gain a much greater degree of insight into the hows and whys of these things.

    4. Re:simplicity by roman_mir · · Score: 1

      absolutely agree with that, and using C to build data structures teaches people more about them than using much higher more abstract languages that already have all these various data structures implemented as parts of multiple libraries.

    5. Re:simplicity by Anonymous Coward · · Score: 0

      Sometimes you just want to get something done, and most libraries in Java, .net, etc are very good and very few bugs.

      yes the underlying stuff is important, but the simple honest truth is that most of the time it isn't worth the time and effort to dive that deep.

    6. Re:simplicity by Anonymous Coward · · Score: 0

      Well, I'm not quite so sure whether

      if(someString.equals(anotherString))

      is so much more abstract than

      if(!strcmp(someString, anotherString))

      it may be more readible, but more abstract?

      Much of the abstractions in Java are the result of its libraries, not the language. That is true of many other languages too, including C.

    7. Re:simplicity by Teckla · · Score: 1

      C is a very simple language

      People keep saying that, but it's not true.

      C is very complicated to program in because it puts a huge burden on the developer. There are 250+ undefined and implementation defined behaviors. The language is a minefield. That's not simple for the developer, that's a damn nightmare.

      The C committee keeps adding more crap with questionable value instead of tightening up the spec. e.g., We're well past the point of having to worry about one's complement machines. They need to start taking a lot of old cruft out.

    8. Re:simplicity by roman_mir · · Score: 1

      Abstract, as in running in a VM, not dealing with the physical machine resources directly.

    9. Re:simplicity by epyT-R · · Score: 1

      As an application user, I find using C/C++ programmed applications over java/.NET because they don't lag and eat tons of ram for their tasks. they really are that much slower.

    10. Re:simplicity by Anonymous Coward · · Score: 0

      Above all, C offers the power of assembly combined with the portability of assembly.

  23. Use the right tool for the right job by Anonymous Coward · · Score: 1

    I don't look at a flat-head screw and grab a phillips screwdriver.

    1. Re:Use the right tool for the right job by Anonymous Coward · · Score: 0

      I'm as tired of single-langujage zealots as I am about single-issue zealots in politics. It's a repetition of the old saw: "When the only tool you have is a hammer, everything starts looking like a nail."

      Argh. Why must every discussion of programming end up using this old "only tool...hammer" phrase. Yes, it gets the point across effectively but it is overused to the point of nausea and I've noticed it being used in situations in which it really doesn't even apply.

      Its as if someone had come up with a phrase and, liking it so much, seeks to find as many places to use the phrase as possible. It would seem, to them, that many situations call for the use of this, their pet phrase. Even to the extent of using the phrase when other phrases would have better served.

    2. Re:Use the right tool for the right job by Hognoxious · · Score: 1

      I'll grant you that string handling in C sucks. It's part of the charm, though, for some projects, because you don't have to worry about the run-time kicking in to do garbage collection at points in your code where timing is critical.

      Why do the two necessarily go together? Is there some reason only revealed to CS PHDs why decent string handling implies automatic garbage collection?

      --
      Confucius say, "Find worm in apple - bad. Find half a worm - worse."
  24. #asm by Anonymous Coward · · Score: 0

    #asm is why i fell in love with C. As a hard-core assembly language coder, what was not to like?

    1. Re:#asm by Thiez · · Score: 1

      Oh I know this one! Is the answer: "Being unable to access the carry flag" ?

    2. Re:#asm by russotto · · Score: 1

      Oh I know this one! Is the answer: "Being unable to access the carry flag" ?

      Correct. How are you supposed to write a short CRC-calculating routine without access to the carry flag? (or, and I'm looking at you nvidia, a multiprecision integer library)

  25. As beginner programmer... by bman49er · · Score: 2

    ...I'm looking into learning more C from an embedded perspective. A lot of Arduino libraries are written in plain C and I'm venturing to learn more about it to write my own libraries and/or edit libraries that come into conflict with others. And if you're wanting to go outside the usual Arduino chip sets (mega328, 168, etc) then it looks like C is the way to go.

    1. Re:As beginner programmer... by jandrese · · Score: 1

      The good thing about C to a beginning programmer is that there isn't much to the language. You don't need a 700 page tome (or to hit google constantly) to figure out what X library function does. There's very little that has weird side effects or anything that isn't immediately obvious. C programs tend to do exactly what they say that do, even when that's not exactly what you're expecting. This is as opposed to something like C++, where you might be looking at a function and wondering why it isn't behaving as you expected not realizing that it was actually overridden later on in the code and where you have to understand the vagaries of the STL and all of the syntax it introduces.

      The downside is that if you're looking at a large project, then there are almost certainly a whole bunch of custom libraries in use (instead of STL) with their own syntax and documentation. You won't see that too much with Arduino projects though, they tend to just do one thing quick and get it done.

      --

      I read the internet for the articles.
  26. If programming languages were like tools... by knarf · · Score: 1

    If programming languages were like tools... then this is what I'd prefer over this when I want to build myself a cabin.

    --
    --frank[at]unternet.org
    1. Re:If programming languages were like tools... by PRMan · · Score: 1

      But with the axe, you really have to understand the tree, the grains of the particular tree that you are cutting. With the chopper, you can just cut anything. But it's noisy and you can't get in tune with nature...

      --
      Peter predicted that you would "deliberately forget" creation 2000 years ago...
  27. Re:because - by 19thNervousBreakdown · · Score: 4, Informative

    That's because there is no difference! I think you meant:

    char* const foo;

    for the second one. const modifies the item to the left, unless it occurs at the beginning of the line, in which case it modifies the item to the right.

    --
    <xml><I><am><so><damn>Web 2.0</damn></so></am></I></xml>
  28. Compilers, Interpreters, and Operating Systems by Anonymous Coward · · Score: 1

    C shines when developing programs like compilers, interpreters, and operating Systems. It is the right level of abstraction for modern hardware. In fact, I've heard that hardware research is dominated by making C code run faster.

    For everything else, which is probably 99% of all software, higher level languages should be used, with C only used sparingly for optimization. Mercurial (hg) is a good example of this; it is written in python but uses some C code to quickly compare diffs and do I/O, and rivals git, which is C with some Perl.

    1. Re:Compilers, Interpreters, and Operating Systems by Ignacio · · Score: 1

      compilers, interpreters

      PyPy

  29. Re:Think of it as standardized assembly programmin by Anonymous Coward · · Score: 0

    A good optimizing (mostly Intel and Portland group) compiler produce hard to guess machine code for non trivial projects, but I never saw an optimizing compiler that targeted embedded device deserving the name optimizing. Overpriced: oh yeah; but optimizing : meh !

  30. It's an awesome zen-language by Anonymous Coward · · Score: 0

    even though i never got much done in it (just some projects at university), I was always having a good time doing stuff in contrast to other languages and was right as you'd call it "in the zone" all the time as I knew i can't just butch stuff together but have to kinda take it slower :D

  31. Negative opinions, says who? by fahrbot-bot · · Score: 5, Insightful

    Though beloved to some, C is a language that many choose to hate. The mass opinion is indeed so negative it's hard to believe that anybody would program anything in C.

    The masses to which you refer are idiots. C is great. It lets you do what you want, how you want. True, you're afforded enough programming rope to easily hang yourself, but you learn not to, and while most things can be more easily done in higher languages (you'll have to pry Perl from my dead, cold hands), many things can only be done in languages like C or its derivatives. C is one of those languages that separates the adults from the kids, so put on your big-boy pants, stop whinging about it and step up.

    --
    It must have been something you assimilated. . . .
    1. Re:Negative opinions, says who? by Teckla · · Score: 1

      The masses to which you refer are idiots. C is great. It lets you do what you want, how you want. True, you're afforded enough programming rope to easily hang yourself, but you learn not to, and while most things can be more easily done in higher languages (you'll have to pry Perl from my dead, cold hands), many things can only be done in languages like C or its derivatives. C is one of those languages that separates the adults from the kids, so put on your big-boy pants, stop whinging about it and step up.

      What a pile of arrogant, chest-thumping uber-geek nonsense.

      C is a really lousy choice in a lot of application domains. You should get your hate on if someone is trying to use a screwdriver to pound nails.

      With its 250+ undefined and implementation defined behaviors, C is a minefield. Sure, if you're writing OS kernels or device drivers or something else where C's advantages outweigh the significant disadvantages, go for it. But in many application domains, C is entirely, utterly inappropriate.

    2. Re:Negative opinions, says who? by geoskd · · Score: 1

      you'll have to pry Perl from my dead, cold hands

      Ahh, Perl. How many languages can you code the same algorithm 5 different ways, all of which work absolutely correctly, and yet you can explain none of them...

      Perl: Psychic interpreting since 1995...

      -=Geoskd

      --
      I wish I had a good sig, but all the good ones are copyrighted
    3. Re:Negative opinions, says who? by fahrbot-bot · · Score: 1

      and while most things can be more easily done in higher languages (you'll have to pry Perl from my dead, cold hands), many things can only be done in languages like C or its derivatives.

      C is a really lousy choice in a lot of application domains.

      Sure, if you're writing OS kernels or device drivers or something else where C's advantages outweigh the significant disadvantages, go for it. But in many application domains, C is entirely, utterly inappropriate.

      Hmm.. First you disagree then agree with me. Either you don't understand the meaning of most and many or you do. Either way, I'm still correct. :-)

      --
      It must have been something you assimilated. . . .
    4. Re:Negative opinions, says who? by Teckla · · Score: 1

      First you disagree then agree with me.

      Ha! You are right. Sorry about that! :-)

  32. What a crock.... by Anonymous Coward · · Score: 2, Informative

    Who are these people that hate C? A tool is a tool and some are better suited to a job then others. Even COBOL has it's place. If you want something to compile to true binary code that runs very fast on the target hardware, then C is a great tool. If you want to slam out some code that will sort of run and look okay to the user, how about Visual Basic? Pascal has it's place as does C++ and even ASP.

    1. Re:What a crock.... by BigMeanBear · · Score: 1

      I'm not sure if COBOL is the best example there.

      --
      += E
  33. right tool for the job by bcrowell · · Score: 5, Insightful

    The mass opinion is indeed so negative it's hard to believe that anybody would program anything in C.

    Huh? What mass opinion? Where's the evidence for this?

    Pick the right tool for the job. C is the right tool for some jobs, specifically jobs like writing drivers or operating systems.

    Historically, C won by having an innovative syntax for pointers, which a lot of people liked, and it also won by being a small language that was easy to implement. Because it was small and easy to implement, it ended up being widely available. Ca. 1980, the joke was that C was like masturbation: it might not be what you really want, but it's always available. A lot of people in 2012 may not realize that in the era when C was winning popularity, people didn't usually have access to free compilers, and for many types of hardware (e.g., 8-bit desktops like the TRS-80), there simply weren't any good development tools. Another big win for C was that because it was so widely available, it became easy to find programmers who could code in it; it fed on its own success in a positive feedback loop. This is why languages like java had C-like syntax -- they wanted to ride the coattails of C.

    IMO the biggest problems have been when people started to use C for tasks for which it wasn't the right tool. It started creeping up into higher-level applications, where it wasn't really appropriate. This became particularly problematic with the rise of the internet. Networks used to be small and run by people with whom you had personal contact, so nobody really cared about the kind of buffer-overflow vulnerabilities that C is prone to. The attitude was that if you gave a program crazy input that caused it to crash, well, what was the big deal? You crashed the program, and you were only hurting yourself.

    1. Re:right tool for the job by vlm · · Score: 1

      people didn't usually have access to free compilers, and for many types of hardware (e.g., 8-bit desktops like the TRS-80), there simply weren't any good development tools. Another big win for C was that because it was so widely available, it became easy to find programmers who could code in it; it fed on its own success in a positive feedback loop.

      History repeats itself in microcontroller land. Microcontroller land is full of "free for students" "free for noncommercial use" stuff. Find me a working Scala implementation for a 384 byte (not megabyte, not kilobyte) 10F220 PIC. And now compile that code for a demo on some TI thing, maybe port it to picoblaze for a FPGA demo...

      --
      "Science flies us to the moon. Religion flies us into buildings." - Victor Stenger
    2. Re:right tool for the job by Anonymous Coward · · Score: 0

      Huh? What mass opinion? Where's the evidence for this?

      This is how Slashdot gets page views, nowadays: Flamebait.

  34. C achieves the status of COBOL & FORTRAN ? by redelm · · Score: 1

    Lets face it -- there are always things to hate. Or, if you are of a more optimistic bent, things to love. Abstraction is tough, and specifying abstraction oxymonically tougher.

    ... Haters gonna hate. With COBOL & FORTRAN faded, they need a new target.

    1. Re:C achieves the status of COBOL & FORTRAN ? by Simon+Brooke · · Score: 1

      COBOL was obsolete before I first started programming, but is still alive and widely used. C has only been obsolete for twenty years or so, so there will probably be dinosaurs^Wpeople still using it in thirty years time.

      --
      I'm old enough to remember when discussions on Slashdot were well informed.
  35. Fortran is better. by Salis · · Score: 5, Funny

    Go ahead. Argue. I dare you.

    v same sig since 2002. v

    --
    Favorite /. tagline: "On the eighth day, God created FORTRAN." And it was good.
    1. Re:Fortran is better. by maroberts · · Score: 2

      Go ahead. Argue. I dare you.

      v same sig since 2002. v

      If a man shouts "Fortran is better" and no-one hears him, he is still wrong.

      --

      Donte Alistair Anderson Roberts - hi son!
      Karma: Chameleon

    2. Re:Fortran is better. by phagstrom · · Score: 2

      The answer is yes in all three cases....

    3. Re:Fortran is better. by Rising+Ape · · Score: 3, Informative

      The main problem with Fortran is Fortran programmers. Or, more specifically, those who started off with F77 or earlier and carried on doing things the same way. For numerical stuff, I prefer F90 or later to C - far fewer ways to shoot yourself in the foot with memory management.

    4. Re:Fortran is better. by Anonymous Coward · · Score: 0

      FORTRAN F77 was my first real foray into programming. It was a 200 level course for engineering majors. I aced it, and later on found that engineering was not for me, but comp sci beckoned. Learned Pascal and a lot of C programming as well. I've forgotten more about those than I remember now (currently an IT general support geek for a smallish manufacturing company).

    5. Re:Fortran is better. by Anonymous Coward · · Score: 0

      I won't argue with you. I'll agree with you. And here is an example.

      Probably the most basic thing you could ever want to know about a string is its length.
      That is defined at compile time in Fortran.

      String length is not defined at all in C. You have to grep (strlen) for the first null character after
      some address to get a number which pretends to be length but is in fact off by one (the null
      character isn't counted).

      This deficiency is pretty much the origin of every buffer overflow that has ever been discussed
      anywhere...and it is impossible to do because Fortran's string definition and handling are
      better than C's.

    6. Re:Fortran is better. by Anonymous Coward · · Score: 0

      (same poster as parent)

      BTW: It is **HIGHLY** amusing to me to see discussions of the sort "C is an
      antiquated fossil, lets get rid of it".

      I've been seeing the same discussions for >20 years about Fortran.

    7. Re:Fortran is better. by excelsior_gr · · Score: 1

      Oh, we hear him alright. And he is right.

    8. Re:Fortran is better. by Anonymous Coward · · Score: 0

      I have had the same experience. Those who started on early versions of Fortran have a hard time using the new(er) features os Fortran 90+, such as dynamic memory and derived data types (structs). I write lots of numerical codes for solving engineering problems, and most of the time I use Fortran, even though I have written some in C as well. Ultimately, the easier memory management and advanced array support is worth using a language considered by many to be strange and unusual. Of course, this is only for numerical analysis. Most other things I write in Python.

    9. Re:Fortran is better. by Salis · · Score: 1

      I 100% agree.
      And f2py is the perfect way to combine the advantages of Fortran + Python.
      It beats SWIG any day.

      I write lots of numerical codes for solving engineering problems, and most of the time I use Fortran, even though I have written some in C as well. Ultimately, the easier memory management and advanced array support is worth using a language considered by many to be strange and unusual. Of course, this is only for numerical analysis. Most other things I write in Python.

      --
      Favorite /. tagline: "On the eighth day, God created FORTRAN." And it was good.
    10. Re:Fortran is better. by Anonymous Coward · · Score: 0

      Not much of an argument. Variadic multidimensional arrays: reverted to "optional" again in the latest C standard since compiler makers did not want to support them. So there still are no standardized calling conventions for libraries dealing with multidimensional arrays. As a consequence, if you want to use several numerical libraries in connection, you better learn about extern "FORTRAN", also because FORTRAN does not have the pointer aliasing problem to the degree C has. Fortran got this more or less right 50 years ago. Which was not all that hard. C insists on still fucking up in that category after all that time.

      Sad really.

  36. Re:news for n00bs by Vlad_the_Inhaler · · Score: 5, Funny

    Move along, nothing left to C

    --
    Mielipiteet omiani - Opinions personal, facts suspect.
  37. Because its fun by Anonymous Coward · · Score: 2, Interesting

    I'm writing a game in C. I spent a lot of time trying to decide what language to use for the game: Java, C#, Python, C++. Ultimately I decided that I wanted to write the whole thing myself so I didn't have to rely on any releases of virtual machines.

    I find it fun. I write in C++ for my job and that is where I spent most of my education. C is an interesting challenge where I don't get all of my comforts. But, it works. I tried writing the game in C++ and I kept getting lost in infrastructure: Objects or get-it-done function? I had to decide all the time. C drops that for a simple set of rules (to me, but I "grew-up" in C++ so I'm used to managing memory) that helps me get the job done. I'm still learning, and I work on infrastructure some to reduce complexity, but its fun.

    1. Re:Because its fun by Morth · · Score: 1

      This is interesting... wanted to mod it but no points, so guess I have to reply.

      I also find C fun to code, and good for many tasks, including string handling which some seem to use as argument to not use it. I'm trying to learn C++ now but it's quite complicated. C is a much simpler language, and you usually spend less time thinking about how to solve the problem than actually writing the code. Maybe if I code enough C++ it'll be the same, but that feels like far far of right now.

      Not that it's a bad idea to design first and write later. It's just not as fun, like you mentioned.

    2. Re:Because its fun by Anonymous Coward · · Score: 0

      Maybe you should learn how to design, instead of agonizing over a languages features.

    3. Re:Because its fun by gman003 · · Score: 1

      I too am working on a game for fun.

      I'm coding it in C++, not true C, but I speak a very C-like dialect of C++. I really only use objects, vectors and strings from the C++ side; I still use printf() and #defines and all those other things C programmers love. I think I only have one case of inheritance in the whole damn project. Someone else in this discussion called such a thing "C+"; I think I like that term. It's C, with some but not all the addons of C++.

      And I, too, chose the language for fun. I could have written it faster in Java. Hell, I could have done it in Flash. But that wouldn't be as fun for me.

    4. Re:Because its fun by Anonymous Coward · · Score: 0

      It always a bad idea to design now and write later. ALWAYS!

      The only people who come up with good designs are people who have already attacked the problem previously... BY WRITING CODE.

      Here are some pro tips from someone who makes $200k/year writing system software, usually in C (because I don't have time to dick around with templates, or the binding and interoperability issues, and all that other crap, which are enticing the way 12-step programs are enticing, but which I know are bad for me because they encourage bad habits, like focusing on the process instead of the product); although, if you use C++ more power to you.

      1) Write first, design later. That is, when you're faced with a similar problem and already know the traps.
      2) Do not write modularly. Do not write OOP. Data encapsulation is your goal, and the API should map to the problem you're addressing, not an abstract pattern. Modular and OOP programming encourage you to expand the scope of the problem, which invariably leads to shitty solutions. YOU DO NOT HAVE A CRYSTAL BALL! So don't pretend like you're saving the world with your forethought. When the world asks for an inheritable class or a loadable module, only then do you deliver.
      3) Don't be afraid to rewrite code. Always rewrite code. But never throw away your old code, because your rewrite will probably suck. You rewrite because writing code is the only way to explore solutions to problems, not by designing an interface from a pre-set palette of patterns.
      4) Stop obsessing over "containers". For the vast majority of my C projects, I use a couple of kinds of lists, and a red-black tree. It works, I never look back. The most important algorithmic issues will never be "containerizable", and require carefully selecting context-specific data structures and selections of data structures for which there will never be a library or pre-existing solution, and if you try to compose it from libraries will it be awkward and a poor fit. This is the essence of good programming---writing problem-specific code---and there is no library or module to solve it for you. Nor should you try to solve it for all humanity with some grandiose API, because no human after you will have the same problem, either. Also, nobody wants to use your shitty solution; they want to use the solution everybody else is using, which may be even shittier, but like the lottery is chosen at random.

      Programmers get into the trap of thinking that if they design ahead of time, they're saving themselves and others time. This is a vicious and false rumor. The only thing that will ever save you time is experience. The only way to get experience is to write code. If you're faced with a big project ahead of you, do not design. Break up the project into several different problems and code, code, code. Try various approaches for each sub-problem until you find one that sings. Then put all the pieces back together. DO NOT THINK HOLISTICALLY. People say that C++ and Java work for "bigger projects". There is no bigger project, just a bunch of small projects which should remain as isolated as practical. If you treat it as a big project, you're going to get a big piece of shit. For example, the Linux kernel: a big pile of shit that only works (and, indeed works well) because there are legions upon legions of people hacking on it 24/7. And, I'm sorry, but moving it to C++ would never solve that. I have nothing against C++, though

      Also, use the best tool for the job, blah blah blah. Those aphorisms are true but are not of much help. The most important rules are the ones above, because they're easy to apply, and there're not predicated on some deeper understanding of the issues.

    5. Re:Because its fun by gbjbaanb · · Score: 1

      yeah, that's the way it should be - C++ doesn't mean "objects all over the place like Java". So write in C, but with RAII and whichever bit of STL makes life easier. I'd rather use a stl::list than code up my own list routines.

    6. Re:Because its fun by Anonymous Coward · · Score: 0

      OMFG, this is absolutely the WORST advice I have ever heard in the history of software development! It HAS to be a troll, there's no other explanation.

      "Write first, design later?" This is equivalent to telling a construction firm to "just start building the house, we'll figure out the design later."

      You know what? Start with the siding and then move on to the framework. We'll worry about the foundation afterward. Just stick the bathroom anywhere; no, it doesn't need to be near the kitchen - we'll move the wetwall later if necessary.

      What's that? You say the house is crap? That's okay; we planned to throw one away (see Brooks) so we'll just tear the whole thing down and start over now that we know what we're doing.

      Sheesh. People: you can't build a thing right unless you know in advance what you're building. "The only thing that will ever save you time is experience. The only way to get experience is to write code." Yes, that's why you have things like education and work experience. You start out building small things and learn to build big ones that way.

      Design isn't easy. You do learn from mistakes, but fer Pete's sake, don't set yourself up to keep making mistakes on EVERY project for all eternity!

  38. What about COBOL? by kenh · · Score: 1

    Why will the development community abandon C while so many still embrace COBOL or RPG?

    --
    Ken
    1. Re:What about COBOL? by Anonymous Coward · · Score: 0

      I got a fever... and the only prescription is more COBOL.

  39. Use the right tool for the right job by Anonymous Coward · · Score: 4, Insightful

    I'm as tired of single-langujage zealots as I am about single-issue zealots in politics. It's a repetition of the old saw: "When the only tool you have is a hammer, everything starts looking like a nail." C has its applications. C++ has its applications Perl has its applications. FORTRAN (remember that language?) has its applications. And so on down the list.

    The fact is, a true professional doesn't have a single tool, he has a whole toolbox full of tools from which to select one, or two, or three, or more to get a particular job done. Look at your auto mechanic: he doesn't try to use a screwdriver when a torque wrench is called for. Look at the Web developer: he doesn't try to write C code to do Web sites. And no one in their right mind would write the heart of an Internet router in C++ or PHP or (shudder) COBOL. The tool has to be matched to the job.

    Sometimes you do the job multiple times, once in an easy-to-debug language to get your algorithms down and your corner cases identified, then a second pass in a language that lets you get closer to the nuts and bolts -- hey, you already have the high-level stuff debugged.

    And then you have people who are more comfortable creating tools to get the job done. I don't know how many times I've written a LEXX/YACC package to generate exactly what I need from a higher-level description...or to give a customer scripting capability suited to the particular task. I call it part of layered programming, and using multiple languages in a project to get the job done right, and in a way that can be maintained.

    Finally, programming style helps reduce mistakes, as do good development tools like IDEs that do syntax highlighting.

    OK, every language has its shortcomings. Even specific implementations of a language will drive you up the wall with its mysteries. But that's part of matching the language to the job.

    I'll grant you that string handling in C sucks. It's part of the charm, though, for some projects, because you don't have to worry about the run-time kicking in to do garbage collection at points in your code where timing is critical. But if the job is text processing without real-time constraints, C is one of the worse choices for a tool. So don't use it for that. Use Perl, or Python, or PHP, or any number of other languages where string handling is a first-class citizen. (For a price. For a price.)

    That's the difference between a true professional and a one-hit wonder: the former knows his tools, how to use them, and when to use them.

  40. Manual Transmission by ClayDowling · · Score: 4, Insightful

    Lots of people hate manual transmissions in cars, too. That doesn't mean there isn't a place for them. I bought a manual transmission truck for the same reason I use C: it lets me get more performance out of lesser hardware, gives me more control, and it's just plain fun to work with.

    1. Re:Manual Transmission by PRMan · · Score: 1

      And yet, in modern cars (even my 9-year-old car), it's literally impossible for a human to outshift the automatic transmisson by any measurement.

      --
      Peter predicted that you would "deliberately forget" creation 2000 years ago...
    2. Re:Manual Transmission by ClayDowling · · Score: 2

      It's been nearly impossible to do that for at least 40 years. I'm not trying to be faster than the machine, I'm trying to be smarter. I know when to downshift for power and control, something the machine can't do because it doesn't have information about the outside world which I do have. I've driven identical models where the only difference was the transmission, and there's a huge difference in how the vehicle handles.

      The same is true with C. When I need the control and the performance, I can get it consistently and reliably from C. It takes knowledge and good habits, just like the manual transmission, but having those, the advantages are within my reach.

    3. Re:Manual Transmission by dbitter1 · · Score: 1

      And yet, in modern cars (even my 9-year-old car), it's literally impossible for a human to outshift the automatic transmisson by any measurement.

      And therein lies the crux of the matter, and exactly the reason C is appropriate for certain projects!

      A *GOOD* automatic transmission, paired with an engine with appropriate torque curve, is indeed better than what a human can do. But considering you don't often get to choose *ALL* the variable parts (crappy engine, off-the-line vs high-end torque, some dumbass put in tree-hugger shift points so your car was Safe For The Children, etc) sometimes you need the "nuclear" option to compensate for it.

      --
      For us carnivores, "Sucking the marrow out of life" isn't a transcendentalist philosophy but a practical instruction.
    4. Re:Manual Transmission by Anonymous Coward · · Score: 0

      Manual transmission weighs less. Costs less. And many automatic transmissions don't let you shift between all gears whenever you like. So yea, an automatic transmission can shift faster, but it doesn't mean it shifts the way you want.

    5. Re:Manual Transmission by Anonymous Coward · · Score: 0

      But yet, automatics are still less fun.

    6. Re:Manual Transmission by Anonymous Coward · · Score: 0

      All the while consuming 30 percent of the power with the torque converter...

    7. Re:Manual Transmission by Anonymous Coward · · Score: 0

      Sure, once the damned automatic transmission decides to shift, then it shifts faster. Time from "hmm I want to shift now" to the shift is done? Human with a manual wins almost every time.

    8. Re:Manual Transmission by HornWumpus · · Score: 1

      How does an automatic know to downshift before you get to the corner? You aren't considering all the modes of measurement, only shift speed.

      --
      John McAfee 'It was like that time I hired that Bangkok prostitute; to do my taxes, while I fucked my accountant'
  41. Litmus test. by HornWumpus · · Score: 5, Insightful

    If you can't code in C you can't code.

    That said, unless you are doing low level/embedded work if you can't find a better tool for the job, you also can't code.

    C should be _every_ programmers second language at the latest.

    The other thing to love about C? Pointers! Pointers to pointers! etc. Coding without pointers might be safe, so is fapping.

    --
    John McAfee 'It was like that time I hired that Bangkok prostitute; to do my taxes, while I fucked my accountant'
    1. Re:Litmus test. by Anonymous Coward · · Score: 0

      C should be _every_ programmers second language at the latest.

      Second language at the latest?
      Any ideas what a C compiler cost in the early 80s for a 8bit home computer, when all home computers booted into basic and assembler was the natural second language?

    2. Re:Litmus test. by Xiaran · · Score: 1

      I cut my C teeth on z80 port of Jame Hendrix Small-C. I suspect there are others.

    3. Re:Litmus test. by HornWumpus · · Score: 1

      Considering my first computer was an Apple][+ yes I do. Before that I used a time sliced LSI-11 at my high school and mainframes at the local CC and University.

      6502 assembler was my third language (after FORTRAN and Basic). C would have been better.

      Times have changed. We learned from the metal up, we had to (remember microcoding HP-41s?). Today's future programmers need to go deep early or they will never really understand.

      --
      John McAfee 'It was like that time I hired that Bangkok prostitute; to do my taxes, while I fucked my accountant'
    4. Re:Litmus test. by Anonymous Coward · · Score: 0

      Pointers are the reason functions receiving arrays can't be optimized properly. FORTRAN got rid of EQUIVALENCE and named COMMON aliasing. With C, arrays are so hopelessly intertwined with pointers and pointer arithmetic, that you can't really prohibit the sort of stuff that kills the optimizer.

    5. Re:Litmus test. by Anonymous Coward · · Score: 0

      If you can't code in C you can't code.
      [...]
      C should be _every_ programmers second language at the latest.

      Nonsense. I use assembler* for low level stuff and Prolog/Basic**/Fortran/Python for high level stuff.

      No need for stinking curly braces languages here for over 35 years.

      --
      * Assembler should be every programmer's second programming language - it was my first programming language (well, actually hexcode was).
      ** That's BBC Basic, where you can just write assembler in your Basic program.

  42. Re:because - by AuMatar · · Score: 4, Informative

    And the funny thing is that most people who write const char* foo really want char const * const foo. You don't want either the pointer or the data pointed at to change. However, almost nobody knows that, so even those who do just use the weaker const char* so people understand the code.

    --
    I still have more fans than freaks. WTF is wrong with you people?
  43. C - The language of Patriots by stox · · Score: 4, Funny

    After all, in our National Anthem, we ask, "Jose, can you C?"

    --
    "To those who are overly cautious, everything is impossible. "
    1. Re:C - The language of Patriots by Anonymous Coward · · Score: 0

      Damn it, are the illegal Mexican's taking programming jobs now too!!

    2. Re:C - The language of Patriots by Anonymous Coward · · Score: 0

      After all, in our National Anthem, we ask, "Jose, can you C?"

      In Mexico, perhaps.

    3. Re:C - The language of Patriots by FrankDrebin · · Score: 4, Funny

      I guess that means we work at a higher-level here with "O Can ADA".

      --
      Anybody want a peanut?
    4. Re:C - The language of Patriots by Anonymous Coward · · Score: 0

      I think I've been waiting my entire life for this post...

      My name is Jose. I am a firmware engineer. Oh yes, I can C!

  44. C is a great Assembly language by Anonymous Coward · · Score: 0

    Note that Python and Perl are implemented in C.

    1. Re:C is a great Assembly language by Ignacio · · Score: 1

      The primary implementations are written in C. Python is also implemented in Java, C#, and yes, even Python.

  45. Re:Think of it as standardized assembly programmin by vlm · · Score: 3, Insightful

    you can pretty much predict what assembly instructions it's going to generate

    Which is really important, because sometimes you end up debugging at that level or working hand in hand with inline assembly code.

    If there is no OS, or you're writing the OS, C is the way to go.

    --
    "Science flies us to the moon. Religion flies us into buildings." - Victor Stenger
  46. Re:because - by DanTheStone · · Score: 4, Informative

    Thank you. "const" modifies the thing that preceded it. Iff nothing precedes it, it modifies the first thing that follows it. It's not terribly complicated.

  47. C is what computing is by Anonymous Coward · · Score: 1

    I didn't "get" C until I studied assembler in college. After learning the basics of assembler and machine code, a little light went off in my head, and I thought to myself, "Ohhhh, so that's why C is like that!"

    C is structured in a way that is very closely related to the way computers function. Maybe if CPU's become radically redesigned, another language would become more practical, but it doesn't look like anything is going to change at that level any time soon.

    1. Re:C is what computing is by Anonymous Coward · · Score: 0

      Maybe if CPU's become radically redesigned, another language would become more practical, but it doesn't look like anything is going to change at that level any time soon.

      Quantum computers will need a concurrent language.

    2. Re:C is what computing is by Xrikcus · · Score: 1

      Even the addition of vector units basically breaks that model. We now need intrinsics or help from vectorising compilers to map to the way the hardware works: C isn't a great match at all.

  48. Re:Think of it as standardized assembly programmin by serviscope_minor · · Score: 1

    Well, C++ basically has all the same properties. GCC, for example will happily target really very small ATMEL micros.

    --
    SJW n. One who posts facts.
  49. C is great by Gordonjcp · · Score: 1

    It's a very high-level language that ultimately compiles to machine code - and you can stop anywhere in between if you want to look at how it looks with the macros expanded out, or if you want to look at how the resulting high-level macro assembler code looks, all the way down to how the machine code looks.

    You've got total control over the code right down to the binary that the CPU runs.

    1. Re:C is great by tuffy · · Score: 1

      Efficiency matters. Python is great, but you don't want to use it for embedded work.

      Or, sometimes you need Python to do something very fast or using as little memory as possible. In those cases, it's easy to drop to C to handle some calculation bottleneck as an extension while letting slow, high-level Python take care of the rest.

      --

      Ita erat quando hic adveni.

    2. Re:C is great by Clueless+Moron · · Score: 1

      Efficiency matters. Python is great, but you don't want to use it for embedded work.

      Actually, I am currently working on an ARM based commercial embedded system that is almost entirely written in Python (on Linux).

      Once you make the leap of adding external ram and flash, which you need to run Linux reasonably, using python is not really a big deal. The whole system is still only a few square cm big; you could hide it in your fist.

    3. Re:C is great by Anonymous Coward · · Score: 0

      I don't understand why people claim that is is "clunky", whenever I read a language speed comparison, e.g.
      http://blog.dhananjaynene.com/2008/07/performance-comparison-c-java-python-ruby-jython-jruby-groovy/
      I look at the implementations and c or c++ always look about the same as the others. Every other language looks about the same as the C version, but it goes much slower. Fine it saves you from memory management, its called THINKING and properly commenting.

      It seems like everyone gets excited for new languages that don't go faster and are more complicated; they're just designed to give CS Majors a hard-on.

    4. Re:C is great by Anonymous Coward · · Score: 0

      But when you do, it's an absolute hoot. (I speak from experience.)

  50. it's all about productivity and automation by Anonymous Coward · · Score: 0

    How many people around do we know that are bad programmers? A LOT
    C is good in good hands, otherwise means disasters and headaches.
    On the other side, even in good hands, C is the wrong tool for a lot of jobs today...
    In the clothes industry there are no old grannies sewing stuff, there is higher level stuff going on, people controlling sewing machines. the talented tailor is for custom and expensive clothes, not for the mass industry.
    The reason why C is so disliked, is that it's time consuming and that it's easy to make big mistakes and leave around big bugs (especially concerning memory management), while using higher level languages with well-thought frameworks can speed up things a lot, save yourself from fixing serious bugs and have a lower knowledge barrier.
    In the modern scenario, a software industrialization is going on: C is not the right tool for most of the tasks: in a real industry it's all about automation.
    C is for talented software artisans, not for hard-hat coders

  51. Unsafe? by Anonymous Coward · · Score: 1

    If you want safe, then the only place that suits you is a mental hospital. C is indeed not safe. It's a Swiss army knife. You can use one of its blades to slit your own throat. Many people still like Swiss army knives though. You cannot carve wood or cut bread with fluffy toy animals.

  52. Language subset by Anonymous Coward · · Score: 1

    All the automotive C programmers I know use a subset of the language -typically a subset of C90. In my team we throw gcc at the source with all the warnings switched on, splint at checks level - no annotations allowed and two MISRA static analysis rule checkers before the cross compiler gets a go. Our code also goes through Matlab/Simulink legacy code tool to give us an additional layer of performance data. After cross compilation the on-board unit tests ensure 100% coverage of the binary after which the whole lot goes through hardware-in-the loop. The vast majority of this is automated and avoiding regression failures is paramount. The build process uses another 10 or so languages including Java for various things. I've seen some more recent languages in use on one other subsystems (the HMI) and the robustness of the software is terrible. When software absolutely has to work every time it's hard to see how we might integrate some other language that further separates us from understanding exactly what is going on. The availability of cheap C cross-compilers for cheap micros (mine is an 8Mhz device) is another factor. The comfort factor of the gauntlet of testing and analysis that we can throw at the source is probably going to be the most difficult hurdle.

    Now if everyone stops learning C and it's not possible to hire good C programmers in 10 years time then you'll see the landscape change overnight.

    We write and maintain about 20,000 lines of source, 40,000 of SIL tests (unit tests) and another 25,000 of hardware in the loop tests for a climate control system for a supercar.

  53. Re: C++ is not equal to C by M.+Baranczak · · Score: 1

    Wrong. C++ == C always evaluates to true.

  54. Re:Think of it as standardized assembly programmin by Anonymous Coward · · Score: 0

    Well, C++ basically has all the same properties. GCC, for example will happily target really very small ATMEL micros.

    If you only use the C part of C++, this can be true. If you use templates or virtual functions, it will not be so obvious what assembly instructions will be emitted. Sticking to C isn't much of a burden if you can't use any of the parts of C++ that are different.

  55. Because it WORKS by gman003 · · Score: 4, Interesting

    C and C++ (I consider them essentially the same, if only because I write them essentially the same) have a few advantages:

    They work. A language update doesn't break your actual programs. It may break your ability to compile them, but you still have a working binary compiled with the old version, which gives you time to make the code work with the new version. You never have to run around like a chicken with it's head cut off because some automatic Java or Python or PHP or __LANGUAGE__ update broke __BIG_CRITICAL_APP__.

    The tools work. You have IDEs that actually work. You have debuggers that actually debug. You've got static analysis tools that actually analyze (I've seen some PHP "static analyzers" that actually just make sure you use a particular code style!). If you want, you can grab the intermediate assembly files and debug *those*.

    The coders work. Sure, C[++] has some really awful language features, but the programmers know about them, know how to use them properly (which, often times, is "never"). It's a language known by any decent programmer. Maybe not used, or liked, but pretty much everyone can read C.

    It does things many other languages can't. You cannot (last I checked) embed assembly snippets in any other major language. There are many libraries that only have C APIs.

    It's fast. Game developers, serious ones, use C++, because even Java is still too slow. And when you have 20,000,000 vertices you need to render every 16ms, speed *matters*. That's why web servers are written in C. That's why operating systems are written in C. That's why other programming languages are written in C. Because sometimes, processor time actually *is* more expensive than programmer time.

    I *like* C. That game I program in my free time? It's C++, but it acts like "C with objects and strings". Sure, I could have done it "faster" in another language, but I know C and like C, for all the reasons enumerated above.

    1. Re:Because it WORKS by Anonymous Coward · · Score: 0

      You cannot (last I checked) embed assembly snippets in any other major language.

      Hooray for Perl's Inline::ASM module!

    2. Re:Because it WORKS by K.+S.+Kyosuke · · Score: 1

      It does things many other languages can't. You cannot (last I checked) embed assembly snippets in any other major language.

      Some major implementations of Common Lisp allow you to write assembly functions in Lisp code. D has inline assembly in the language spec. Ruby and Perl have Inline modules allowing to write code in other languages, including C which can have assembly snippets, etc.

      --
      Ezekiel 23:20
    3. Re:Because it WORKS by Anonymous Coward · · Score: 0

      You fail to realize that modern C++ is actually a fundamentally different and much more advance language than C.

      I always get a little sad when I see C and C++ mentioned in the same sentence. Writing C-style C++ code isn't doing the C++ language any favors, and neither should one of those programmers call themselves a C++ programmer...

    4. Re:Because it WORKS by Anonymous Coward · · Score: 0

      Serious game developers do not use C/C++. Serious game engine developers use C/C++. Most tool stacks, whether it be for game development, web development, business applications, will use the right tools for the right job at a specific level of the stack. C++ is used for the performance critical areas e.g. "20,000,000 vertices you need to render every 16ms"...but a lot of higher level logic will be developed in tools better suited for a specific task e.g. SQL, Lua, C#, Java etc.

    5. Re:Because it WORKS by Anonymous Coward · · Score: 0

      FWIW, you can embed assembly language snippets in Delphi code too

    6. Re:Because it WORKS by Anonymous Coward · · Score: 0

      Apparently, you are too young to have faced WIN16 vs WIN32 vs WIN64 or recently: Linux X32 vs Linux X64 ABI.

      What about generic C code that works "perfectly" on 32-bit and breaks on all X86-64 platforms ?

      We had the same issue when 16-bit code got promoted to 32-bit CPUs.

      It's very hard to get any piece of C or C++ code "right".

      It's even harder to get any piece of C or C++ code "right"... over "time", when CPU / architecture / design / feature changes.

      Almost all commercial C code base I have seen (about two dozen large code base as a consultant)
      had hundreds of buffer overflows, integer overflows, logical errors, exploitable code,
      non-thread-safe issues, locking issues, apart few exceptions here and there.

      They have NDAs and closed source repositories for a valid reason, nobody wants to see their spaghetti code mess.

      Even well-known open source projects such as OpenBSD, OpenSSL, Linux Kernel, Apache,
      among others have issues with their C code.

      The only commercial exception I have seen was a C++ code base, where it was prohibited by design to use certain features,
      except in very well identified code parts that were code reviewed by at least 5 seniors, for each release,
      then tested live in parallel for 6 months before going in production.
      And by far, this is not the industry norm, which is more like: "if it compiles, then ship it!" (TM).

    7. Re:Because it WORKS by dkf · · Score: 1

      C and C++ (I consider them essentially the same, if only because I write them essentially the same) have a few advantages:

      But they're not the same, and the general practice of their use is very much not the same. C and C++ are diverging somewhat, and it's definitely the case that what is good practice in one is often bad practice in the other.

      They both have their niches though. C's good for low-level work, embedded systems, operating systems, runtimes for other languages, basic libraries. For almost anything you might choose to do, some of it is likely to be founded on something written in C. C++ is mostly higher-level, and it stakes a claim to be able to cope with going quite a lot higher level than C. It mostly succeeds with that, but it's connection with the low-level world of C is both its strength (it can be very fast) and its weakness (it can be very unsafe). What's more, there have been a number of technical mistakes made during the language's development that have awful consequences down the line (e.g., the multi-rooted class hierarchy, access to operators without requiring mathematical structures).

      Overall, the biggest problem of all are the people who insist that a single language be used for everything. Or "idiots" as I like to call them. Languages are abstractions, and abstractions both empower you and restrict you. Indeed, they empower by restricting; you're empowered by not having to think about everything, but in turn that means there are things you can't think about. Since you can't have one without the other, you have to trade-off carefully and bear in mind that sometimes the abstraction was wrongly selected and not be too proud about it.

      --
      "Little does he know, but there is no 'I' in 'Idiot'!"
    8. Re:Because it WORKS by Anonymous Coward · · Score: 0

      An abacus also works, it doesn't mean it's anywhere near practical or efficient to work with for general porpuse computing.

  56. Portability by Anonymous Coward · · Score: 2, Interesting

    Among the many benefits of C overlooked by some apparent `mass opinion' is portability. C compilers are easy to create. Things written in C can be compiled on platforms that provides a C compiler. C has been the lingua franca of mature system software for over 40 years; it's the first thing you write after you have a working assembler.

    This situation won't change until someone makes a real alternative. Lots of things purport to offer an alternative but are actually not; they are complex and require sophisticated compilers and memory management schemes. C is simple. Any alternative must be at least as simple to be considered.

    It isn't hard to imagine an alternative. C is not perfect. The problem, in my opinion, is that no one has really tried; language designers seem to be interested in only higher level problems and are happy to muddle along ignoring the flaws of C.

  57. Re:Think of it as standardized assembly programmin by jandrese · · Score: 1

    Yes, but it won't work at all unless you explicitly tell your compiler to ignore the vast majority of C++ features and basically just write C in C++. You can use objects without incurring too much bloat, but don't even think about touching the STL or templates in general.

    For comparison I made up a pair of Hello World programs, one in C and one in C++. The C version compiled down to 3220 bytes (still outrageous), but the c++ version came in at a whopping 4876 bytes, completely blowing away the 4k memory budget the op talked about.

    --

    I read the internet for the articles.
  58. On roll with dumb Ask Slashdot questions lately. by multicoregeneral · · Score: 1

    First, in why does php suck so much, we got to see all kinds of nonsense answers by people who don't understand programming fundamentals. In why do we need command lines anyway, we got to see people discuss getting rid of the command line, as though it's a legitimate option. And in, why can't I understand the core principles of C, we're going to see more of the same. I have a question for Slashdot: Why are you publishing nonsense questions?

    --
    This signature intentionally left blank.
  59. Thanks /. by betterunixthanunix · · Score: 1

    Well, I was going to try to prove my point by giving an example disassembly from SBCL, to show that a high level language with modern features can be compiled to bare metal, but the lameness filter stopped me. Still, Lisp has been compiled to metal for a long time, and it is not nearly as painful as using Pascal, Fortran, or C (unless you really hate parens).

    --
    Palm trees and 8
  60. Re:because - by Mike+Buddha · · Score: 5, Funny

    And the funny thing is that most people who write const char* foo really want char const * const foo. You don't want either the pointer or the data pointed at to change. However, almost nobody knows that, so even those who do just use the weaker const char* so people understand the code.

    Hmm. I wonder why there's so much animosity towards C? It's a mystery.

    --
    by Mike Buddha -- Someday the mountain might get him, but the law never will.
  61. And the Worst Language of the Week award goes to.. by Anonymous Coward · · Score: 0

    C!

    And every other language ever written comes in a close second.

    Tune in again next week when we pick another Worst Language of the Week.

  62. C is the hole in the donut by PolygamousRanchKid+ · · Score: 0
    • C is the whole donut.
    • C is the yin without yang.
    • C is toast without bread.
    • C is why doctors ask you to cough.
    • C is the Universe with decreasing entropy.
    • C is the space in between the pixels on your screen.
    • C is why venetian blinds have curved slats.
    • C is evaporated herbal tea without the herbs.
    • C is the force which keeps Mickey's ears parallel at all times.
    • C is the reason why pasta in different shapes gets different names.
    • C is allowed.
    • C is the reason that I'll never need to retire.
    • C is What's To Love About C.
    --
    Schroedinger's Brexit: The UK is both in and out of the EU at the same time!
    1. Re:C is the hole in the donut by Anonymous Coward · · Score: 0

      C is for "Cookie", that's good enough for me!

      http://www.youtube.com/watch?v=Ye8mB6VsUHw

    2. Re:C is the hole in the donut by TeknoHog · · Score: 1

      fnord

      --
      Escher was the first MC and Giger invented the HR department.
  63. Re:news for n00bs by LS1+Brains · · Score: 1

    I C what you did there.

  64. Re:because - by Anonymous Coward · · Score: 0

    Almost nobody knows that? I guess we've discovered the difference between software "engineer" and "programmer".

  65. Re:because - by tigre · · Score: 1

    And the funny thing is that most people who write const char* foo really want char const * const foo. You don't want either the pointer or the data pointed at to change. However, almost nobody knows that, so even those who do just use the weaker const char* so people understand the code.

    You might actually want the pointer to be able to change. You may have a pointer to _some_ literal string, but want to be able to change _which_ literal you are pointing to.

  66. Speed, predictability, low memory usage. by Anonymous Coward · · Score: 0

    It's essentially a high level assembly language.
    It's generally fast, and very memory efficient and compiled-code-size efficient. It's predictable.
    I use it where I need these features.

    I don't actually see much hate for C around to be honest. Anyone who outright hates it can probably have many of their other opinions safely ignored.

  67. Simplicity & portability by SplashMyBandit · · Score: 1

    C is great because the language as simple and portable. The complex goodness comes in the libraries. Java tries the same approach, but modernised (hence, the enormous success of C and Java). C++ does not have simplicity as its goal, which makes it horrid to read someone else's code.

    1. Re:Simplicity & portability by GodfatherofSoul · · Score: 1

      I wouldn't call C "simple," I'd call it "small." You can probably learn the entire syntax in a day, but it takes years to master such low-level memory management and pointers.

      --
      I swear to God...I swear to God! That is NOT how you treat your human!
  68. It's the language closest to assembly. by Foske · · Score: 1

    It's the language closest to assembly, which makes it a great language for microcontrollers. In fact, most of the microcontrollers only come with assembler and C programmer, though many understand some convenient C++ features.

  69. Re:because - by jd · · Score: 1
    --
    It's a small world and it smells funny; I'd buy another if it wasn't for the money; Take back what I paid (SoM)
  70. Re:because - by TwineLogic · · Score: 5, Insightful

    Oh, no, it's not a mystery. The animosity comes from ignorance and lack of ability. Many newer programmers have never programmed in assembly language or C, and would not be able to build a computer out of logic chips. This same demographic has learned Java and believes that Hashmap is a magic O(1) thing you can just smear onto any algorithm. C was initially popular among people who were, in fact, able to build computers out of 7400-series logic, or even transistors, if need be. In other words, the animosity comes from those who aren't qualified to judge.

  71. Basis of the article not necessary true... by Anonymous Coward · · Score: 0

    The writers of the original article obviously haven't checked the latest Tiobe ratings:

    http://www.tiobe.com/index.php/content/paperinfo/tpci/index.html

    Looks like either C isn't that despised or a lot of people are using it in spite of hating it.

    Hahahahahaha...

  72. Never give C to someone who can't program. by Anonymous Coward · · Score: 0

    Never give a sword to a man who can't dance

    Confucius

  73. oh slashdot! by Anonymous Coward · · Score: 0

    1) make a blog post
    2) link to it in a slashdot submission
    3) ????
    4) profit!

  74. From a Java Developer by Anonymous Coward · · Score: 0

    Hi,

    I'm a fulltime Java Developer and has been for a couple of years (10+). My heart is tho still with C, nothing bets the understanding your get of how things works, as the understaning your get when developing in C. It helps me in my Java work, since everyone seems to come too me when noone else can solve the problem. I been hunting Java problems throw the JVM down to the OS, and even to device driver layers, and then back up again through the OS and JVM to find a wrongly implementation of how resends are done in the JVM. Without my knowledge of C, I would be lost. C is fundamental to me.

    Dont hate it, learn it, you will learn alot of "how and why" things are like they are.

  75. Re: C++ is not equal to C by 91degrees · · Score: 1

    Wait, what does happen here?

    Isn't it incrementing C, taking the previous value of C, and comparing with the new value of C? Or does the increment only happen after a sequence point?

  76. Re:because - by AuMatar · · Score: 1

    Sometimes. But let's be honest- how many times when you write const char* foo="some string" do you really want that? It's a miniscule fraction of the time. Almost all of them should be double const.

    --
    I still have more fans than freaks. WTF is wrong with you people?
  77. Quarter megabyte hello world by tepples · · Score: 1

    *The iostream libraries.

    Well, I like the type safety of the C++ library.

    But are you willing to spend a quarter megabyte on type safety? I tried making hello world with <cstdio> and hello world with <iostream> with statically linked GNU libstdc++. The <iostream> versions were about a quarter megabyte bigger on both i686 and ARM-Thumb. And no, you can't use a dynamically linked C++ standard library on an embedded system that doesn't already have such a library in ROM (such as a handheld video game system) or on a compiler whose C++ calling convention doesn't match that of the operating system vendor's own C++ standard library (such as MinGW).

    1. Re:Quarter megabyte hello world by serviscope_minor · · Score: 1

      But are you willing to spend a quarter megabyte on type safety?

      Generally, yes. Most of the time, that kind of size difference doesn't even begin to come into it, and the speed of development is overwhelmingly the largest factor. Certainly, if I'm using gcc and iostreams, the platform is large enough that the 250k of (potentially shared) code doesn't make much, if any difference./

      If it did, it would probably be one of the later things to try and optimize.

      --
      SJW n. One who posts facts.
    2. Re:Quarter megabyte hello world by Short+Circuit · · Score: 1

      It might be worth trying recompiling the standard library optimized for size, and see if that helps. There are also C++-to-C compilers which may work.

  78. All languages are equivalent by kiick · · Score: 1

    All languages are equivalent in what they can do (See Turing Machine). However, you pick a language that makes what you want to do easy. For twiddling bits, for writing fast algorithms, for controlling hardware, for lots of common programming tasks, C is the simplest language that makes those tasks easy. There are things that are tedious to do in C (like doing complex things with strings), so in those cases you pick another language that is more appropriate. Something that might take up 5 lines of Perl could take pages of C code, but there's no point in writing a Perl script for something that can be easily done with a few lines of C. The C program will be smaller and faster, and probably easier to understand.

    So there are lots of things to like about C, when it is the appropriate language for the task.

    1. Re:All languages are equivalent by badkarmadayaccount · · Score: 1

      Tell me what can C do that Ada can't do better?

      --
      I know tobacco is bad for you, so I smoke weed with crack.
  79. C! by Anonymous Coward · · Score: 0

    My girlfriends name is C...

    A video of her:
    http://www.youtube.com/watch?v=UPjkdJovqkU

  80. Embedded Systems by Anonymous Coward · · Score: 0

    Programming an Embedded system that needs to "Just work"?

    Can't deal with the jittery Java garbage collector that can mean the difference between missed input and lag?

    Need sub ms guarantee response times?

    Need a binary that runs in a few kb of ram, much less a few Gb?

    Medical devices, embedded systems, stuff that can't tolerate a few gb of bloatware, and need ns to sub-ms response time.

    Imagine a pacemaker programmed in Java...sorry, can't process that input right now, garbage collection.

    1. Re:Embedded Systems by Thiez · · Score: 1

      Not that I would recommend running Java on a pacemaker, but there is really no need for a pacemaker to create new objects, so the GC would never run anyway.

  81. Re: C++ is not equal to C by Thiez · · Score: 1

    If C is volatile and changed by a different thread, your statement might actually evaluate as false.

  82. What's To Love? by Greyfox · · Score: 2
    One, it's simple and reasonably consistent. If I recall correctly, the language only has 24 keywords. Everything else is library. You may have some complaints about the library, but that's not really a language issue is it?

    Two, the library. You may have some complaints about the library, but in the right hands a person really can control every aspect of a UNIX system with it. I've had to write process watchdogs at a couple of different companies. These were programs that would kick off another process and monitor its status. That is remarkably easy to do in C. It's a little harder to do correctly but it's still pretty nice. I still hand-code socket servers from time to time. That's also pretty easy with C and the standard library. Actually IPC in general is quite accessible. Handling time... easy. Checking filesystems to see how many blocks are left... easy. The list goes on.

    All those utilities we take for granted are all implemented in C, and you can get at all that functionality if you need to. Once you've done some system level programming, the constraints of less mature languages become annoying very quickly. Compare the capabilities of Java's "Process" to what you can do in C, for example.

    Sure it's dangerous. Sure there are corner cases you might get caught at. But really, the corporate software development model is far more dangerous, no matter what the language. If you code small, tightly focused libraries and unit test them, whatever language you use is probably pretty safe. If you code some monolithic abomination with half a million lines of tightly coupled, untested code, you're probably going to run into problems anyway. In 20 years of software development, I've never seen anyplace actually write smaller libraries and link them in. Hell most of the places I've worked either didn't have version control or were using it incorrectly. If your company puts up with bad programming, it really doesn't matter what language you're using.

    --

    I'm trying to teach myself to set people on fire with my mind... Is it hot in here?

    1. Re:What's To Love? by ADRA · · Score: 1

      You give some nice points, but I think they're better directed for software in general. Regarding big projects, I see the rationale on both sides of the argument. A project has a mission, and that mission is to get things done as fast as possible within the scoped bounds of the project. Unless the modularization of the code pieces makes development faster (must more often cleaner, but far less often faster), then a PM or senior development lead will have to make desicion if its worth chopping off pieces of code into modules/libraries which can be more easily worked with afterward. Given the amount of realistic buffer time a project has between development time and project end dates, the most likely answer will be that its not worth the time in 'getting it right'.

      The sad thing about this tradeoff is that it will often bleed into subsequent projects. Those projects will inherit the technical debt that came with doing it sloppier but faster in the prior projects. That's why large companies really should have passionate architects that are outside but in advisory roles for projects, so that they can make the unbiased opinion of what's good for the project vs. what's good for the company.

      --
      Bye!
    2. Re:What's To Love? by Anonymous Coward · · Score: 0

      One, it's simple and reasonably consistent. If I recall correctly, the language only has 24 keywords.

      Wasn't that the number of operator precedences?

    3. Re:What's To Love? by Greyfox · · Score: 1

      Ah, Google says 32 keywords. Still not that many. It's always fun writing your own C grammars with Lex. Sadly that's not something you see that often anymore. I had a company ask me to do a C comment counter a few years ago, as part of an interview. They gave me a couple of times and I wrote it using Lex. They said mine was the only one that worked correctly with all their test cases, and they thought I was probably overqualified for the position. Oops!

      --

      I'm trying to teach myself to set people on fire with my mind... Is it hot in here?

  83. Re:because - by Anonymous Coward · · Score: 2, Funny

    The animosity comes from ignorance and lack of ability. In other words, the animosity comes from those who aren't qualified to judge.

    Exactly. Unless you guys can make device drivers in Visual Basic like me, you're not qualified to put down the language.

  84. Re: C++ is not equal to C by Brian+Feldman · · Score: 1

    (Except in C++, where it could mean anything.)

    --
    Brian Fundakowski Feldman
  85. Simple: C is the new assembler. by Anonymous Coward · · Score: 0

    Are we done here? ;)

    TL;DR: There is low-level code and there is high-level code. You use the best tool for the job.
    Inside a kernel driver, C is just more natural.
    Inside a helper script, e.g. Bash/Perl/Python/Ruby/JavaScript/... is more natural.
    Inside a user application, there are others. (Not naming names = no flaming flames. :)

    And then there is Haskell... ;)

  86. Java Programmers Horrified by Suggestion of C by Anonymous Coward · · Score: 1

    From one of my facebook posts a few months back...and a true story (with a bit of embellishment):

    So I mentioned at work in the company of a flock of Java programmers that I was playing around with writing web applications in C and C++. The collective gasp of horror...and I mean literally HORROR...on these people's faces was hilarious. Apparently, amongst many Java developers, writing anything in C or C++ is equivalent to making a pact with the Devil. Now, I agree that there are A LOT of reasons to NOT write web apps in C or C++, but the outright FEAR in the eyes of these developers of my snubbing the Programming Gods by writing code without my talisman of garbage collection, my sword of strong typing, my shield of virtual machines (which we all know are just interpreters), and heaven forbid, going out to do battle without ANY object-oriented paradigms (in the case of C...and keep in mind...the ENTIRE world...without exception...MUST be modeled as a class...even something like an integer) brought these people to their knees shaking in holy terror. Ah well...the circle is complete...as that is what I am certain my mother referred to me when i was but a small lad...Holy Terror!

    1. Re:Java Programmers Horrified by Suggestion of C by Anonymous Coward · · Score: 0

      I have seen this at my place of work as well. There is an active effort to eliminate native code that makes no sense to me. It seems that Java programmers can't function without training wheels.

      I guess the thing I find funny is that the JRE essentially provides a minimal set of capabilities - whatever could easily be implemented on all platforms on which Java is supported. But some systems have far more capabilities than this, and the question is how then to take advantage of this? Sadly the answer is that they don't - they end up with an application that is more difficult to use and configure, but one that "runs" everywhere.

    2. Re:Java Programmers Horrified by Suggestion of C by Anonymous Coward · · Score: 0

      Your CPU is just an interpreter too.

    3. Re:Java Programmers Horrified by Suggestion of C by FormOfActionBanana · · Score: 1

      Just wondering if you've had anyone review your buffer overflows, AC?

      --
      Take off every 'sig' !!
  87. Subset holy wars; STL without exceptions by tepples · · Score: 3, Insightful

    One of the best features about C++ is that you can define your own subset that you'll use.

    One of the worst features about C++ fanboys is that if their subset doesn't match your subset, you get subset holy wars with "no true Scotsman" fallacies all over: "no true C++ program uses <cstdio>".

    Worried about exception handling? Then don't use them!

    The entire STL uses new, which throws std::bad_alloc on failure, instead of new(std::nothrow), which returns NULL like old-school std::calloc. So how would one handle out-of-memory conditions on an embedded system with no swap file without A. being unable to use the containers and algorithms of the STL or B. reimplementing the whole STL yourself to use instead of throwing std::bad_alloc?

    1. Re:Subset holy wars; STL without exceptions by gbjbaanb · · Score: 1

      IIRC STLPort is built without exception handling, or even if it doesn't, there are implementations designed for embedded systems that are a bit more embedded-friendly.

      BTW, new should return std::bad_alloc, 'cos you can't new an exception structure if you've got no memory left that caused the initial new to fail.

      as for subsets - c'mon, you get holy wars over bracket placement and whitespace. Arguing over language features is a strawman given that.

    2. Re:Subset holy wars; STL without exceptions by Anonymous Coward · · Score: 0

      Just overload the global new / delete operators and have them call malloc / free.

    3. Re:Subset holy wars; STL without exceptions by Anonymous Coward · · Score: 0

      One of the best features about C++ is that you can define your own subset that you'll use.

      One of the worst features about C++ fanboys is that if their subset doesn't match your subset, you get subset holy wars with "no true Scotsman" fallacies all over: "no true C++ program uses <cstdio>".

      Worried about exception handling? Then don't use them!

      The entire STL uses new, which throws std::bad_alloc on failure, instead of new(std::nothrow), which returns NULL like old-school std::calloc. So how would one handle out-of-memory conditions on an embedded system with no swap file without A. being unable to use the containers and algorithms of the STL or B. reimplementing the whole STL yourself to use instead of throwing std::bad_alloc?

      if you're worried about memory what the fuck are you using stl for????

    4. Re:Subset holy wars; STL without exceptions by tepples · · Score: 1

      If the allocator returns NULL, many STL implementations will exhibit undefined behavior.

    5. Re:Subset holy wars; STL without exceptions by PaladinAlpha · · Score: 1

      So write that logic into your allocator. Generally there are two options when your allocator gives you NULL; that's either retry or abort, and writing those into your allocator is trivial. That's what's so good about C++, btw. (You're still incurring no runtime overhead aside from whatever extra cycles you are burning in your allocator with these checks, which you needed anyway.)

    6. Re:Subset holy wars; STL without exceptions by Anonymous Coward · · Score: 0

      The entire STL uses new, which throws std::bad_alloc on failure, instead of new(std::nothrow), which returns NULL like old-school std::calloc. So how would one handle out-of-memory conditions on an embedded system with no swap file without A. being unable to use the containers and algorithms of the STL or B. reimplementing the whole STL yourself to use instead of throwing std::bad_alloc?

      If you define operator new() in the global namespace, then it will override the default one provided by the standard library. You can just make a wrapper around malloc and handle out-of-memory situations yourself.

    7. Re:Subset holy wars; STL without exceptions by Anonymous Coward · · Score: 0

      overload operator new.
      http://stackoverflow.com/questions/1706776/avoid-stdbad-alloc-new-should-return-a-null-pointer

  88. Platforms with no native code support by tepples · · Score: 1

    I have a C library. I can dynamically import it into C, Python, Java or C# fairly easy, on any platform

    I'd temper that to "almost any platform". Otherwise, good luck importing a C library into a C# project on Windows Phone 7 or Xbox 360 XNA. These platforms have no support for native assemblies and throw a security exception when you try to P/Invoke. Likewise, some pre-iOS smartphone platforms based on Java Micro Edition give no JNI privileges to user applications.

    1. Re:Platforms with no native code support by ByOhTek · · Score: 1

      Correct, on platforms where C is not available,then you are SOL - but then again, on those platforms, your language is almost always chosen for you anyway.

      --
      Self proclaimed typo king, and inventor of the bear destroying coffee table (patent not pending).
  89. Simple, Effective, Universal by Doc+Ruby · · Score: 1

    C is basically logic algebra. Its syntax and computing model are the essence of iterative processing. It's a great lingua franca (universal language spoken by all, even if it's frequently far from the best in expression). Most programmers and machines speak it.

    If C didn't exist, we'd have to invent it. All hail the almighty C!

    --

    --
    make install -not war

  90. Re:because - by Anonymous Coward · · Score: 0

    Excellent! It was a trick question. Of the many C programmers I've interviewed,
    few knew. I only gave serious consideration to the ones that knew they were the same.

    --
    AC

  91. Because it's portable and bindable by Anonymous Coward · · Score: 0

    Your code, in C, can be ported to almost any modern platform, and almost every (if not absolutely every) very high level language lets you call c functions and examine c data. That's why you write in C.

    I'm not sure I've met many good programmers that hate C. It's a good language, very simple and does what it's supposed to. I like a lot of other languages better, and would prefer to program in them, but C was never trying to be anything more than it is: A portable system level language.

    Now, C++, there are lots of good arguments for why it's just a bad language. Useful, heck yea, but it's big, complicated, inconsistent, supports c way too closely, but doesn't support c (see: new, memset and your program crashing). That said, I kind of love templates, as much as I hate them so very much.

  92. My First 'C' class by Anonymous Coward · · Score: 0

    I'll always remember my first 'C' class. We asked to define what a pointer was. The professor asked a student to stand and point to a wall. He then said, "You're a pointer.". I still don't get it.

    1. Re:My First 'C' class by darkwing_bmf · · Score: 1

      A pointer is something that points to something else. He was trying to make it easy for you to visualize the concept but apparently he failed.

  93. Re:Think of it as standardized assembly programmin by Anonymous Coward · · Score: 0

    I remember writing some rather simple program in C that compiled to an executable of about 18 kbytes. I then spent 2 days splitting up libraries and stripping out code until that same functional C code compiled out to about 8 kbytes. That was a few years back, when Microsoft offered their first in-house C programmer.

    {Yeah, I am a really really old fart.)

  94. Re:Think of it as standardized assembly programmin by Anonymous Coward · · Score: 0

    So, the C version fits (barely) in the 4K limit? Big deal, you still only have a program that prints "hello, world."

  95. Re:Think of it as standardized assembly programmin by serviscope_minor · · Score: 1

    You can use objects without incurring too much bloat,

    Well, that's already nicer than using plain C.

    but don't even think about touching the STL or templates in general.

    You're not going to be using std::vector on an atmel micro, but then you're probably not going to be using iostreams either. If you're using printf, then it's certainly not the C standard one with locales and whatever.

    Using something like std::sort, std::heap or std::bitset is not going to induce bloat.

    --
    SJW n. One who posts facts.
  96. What's not... for *good* programmers? by whitroth · · Score: 1

    If you can't get into serious trouble in a language, you're also limited in the good stuff you can do.

    Oh, I know, it's *so* old, it wasn't invented in the last five years. Oooh, cooties, it was invented last *century*: who'd want to use *that*... never mind it's fast, and can be clean and elegant, if you got past the crap you wrote when you first got out of school, with no error checking and handling, and whatever the professor who made the biggest impression on you's Favorite Tool was (i.e, I worked with a guy many years ago who seemed to think that *everything* should be done with recursion).

    Easier to debug, too, when you don't have a stack of inherited increasingly complex stuff to write "hello, world".

                mark

  97. C is great by Erich · · Score: 4, Insightful
    • It is much more portable than assembly
    • The performance overhead compared to assembly is reasonable
    • Most people find it simpler to develop in than Forth
    • It's not the horrible monster that C++ is

    This makes it very nice for all kinds of embedded environments.

    Efficiency matters. Python is great, but you don't want to use it for embedded work.

    --

    -- Erich

    Slashdot reader since 1997

  98. many reasons by Anonymous Coward · · Score: 0

    I'm not a scientist or an academic working with the design pattern of the month; I'm an engineer and I need to get things done.
    I write high performance code.
    I understand the hardware.
    I want to talk directly to the hardware efficiently with no VM in my way.
    I know what I'm doing and I know how to clean up my mess; I don't need garbage collection or an interpreter to hold my hand
    I know how to write secure code, work elegantly, efficiently and securely with multiple levels of indirection and use it to my advantage. Pointers do not scare me.

  99. Bad quiz: "implementation defined" not an option by tepples · · Score: 2

    Fully one-fourth of these questions ask about aspects of a specific implementation, not the C standard, and "implementation defined" is not an option.

    Questions 3 and 18 on the quiz assumes that int is 32-bit. Question 3 assumes that unsigned short automatically gets promoted to signed int because no values are lost, but that's true only if sizeof(signed int) > sizeof(unsigned short). It's not true on platforms with 16-bit int, for example. Question 18 states that the answer is correct "as long as the int type is wider than the short type", which again is not the case if sizeof(short) == sizeof(int). Question 12 does the opposite; the answer is wrong if int is 64-bit.

    Questions 4 and 5 cover implementation-defined behaviors and assume familiarity with the x86 and x86-64 ABIs. I happen not to own an x86-64 machine, and I understand some widely used ARM ABIs differ by having char default to unsigned. Question 4 implicitly asks about x86 and x86-64, while question 5 dishonestly doesn't mention which implementation is used until the answer.

  100. C considered too restrictive by mwillson · · Score: 1

    Let's face it, C is just an overblown BCPL - let's get back to basics...

    -mark

  101. Unpredictable constructor order by tepples · · Score: 0

    C++ isn't going to "slip anything in."

    So what's the standard way to guarantee that one object will be constructed before another object begins to be constructed? If this is undefined in C++, as I suspect, what's the standard workaround?

    1. Re:Unpredictable constructor order by shutdown+-p+now · · Score: 1

      So what's the standard way to guarantee that one object will be constructed before another object begins to be constructed? If this is undefined in C++, as I suspect, what's the standard workaround?

      Objects in variables (whether static or auto or member) within a translation unit are constructed in the order in which they are defined. So just define them in the order you need.

      If you mean globals referenced across translation units, then the usual workaround is to hide the global inside a getter function as a local static, and export that function. Local statics are initialized on first call, so unless you have cyclical dependencies, your order of initialization will match the use order.

    2. Re:Unpredictable constructor order by tepples · · Score: 1

      If you mean globals referenced across translation units

      Yes. For example, in Allegro or SDL, one must initialize the entire library before opening a window, and one must open a window before loading any textures (so that the pixel format will be known), and one must load the font texture before displaying "Hello World".

  102. And it's easy to spell! by davidwr · · Score: 1

    C
    Sea
    See

    OK, maybe not so easy after all.

    --
    Knowledge is how to play a game, intelligence is how to win, wisdom is knowing what game to play.
    1. Re:And it's easy to spell! by Xiaran · · Score: 1

      And how do you pronounce char?

    2. Re:And it's easy to spell! by davidwr · · Score: 1

      In all examples below: /* variable, function, object, and other defintions and declarations are left as an exercise to the reader */

      In C:
      pronounce(u,achar);

      Or if everyone pronounces char the same way,

      pronounce(achar);

      In C++:

      u->Pronounce(achar);

      or, if everyone does it the same way,

      achar->Pronounce();

      --
      Knowledge is how to play a game, intelligence is how to win, wisdom is knowing what game to play.
  103. Reasons to program in C (and C++) by Anonymous Coward · · Score: 0

    Reaons for C

    - It is fast and for people (like me) doing numerically analysis a factor of 2 or 3 matters (and this pretty much leaves C,C++ or Fortran). Memory usage especially total control over allocation is also vital in many cases.
    - For system programming or embedded systems or everywhere else where computational resources matter (and that eclipse needs about half a minute on a brand new computer indicates to me that this is also true for many things on the desktop)
    - Because the syntax allows the programmer to write concise code that is easier to read (I prefer a++ instead of a = a +1 as is the case for example in matlab)
    - pointers to primitive types (i.e. int, float, ...)
    - and many more

    Reasons to use C++

    - Templates. Allows to write modular code without sacrificing performance
    - Typesafe lists (i.e. std::vector)
    - Operator overloading (who wants to write matrixA.dot(matrixB.dot(matrixC))? )
    - not everything has to be a class
    - and many more

    I also don't understand the concept of many of the "convenient" languages (with the exception of Python and C# perhaps). Pretty match everything related to mathematics I can't do conveniently if I can't overload operators (Java does not support that for example). I see absolutely no reason to put everything in a class, etc...

  104. Legacy Code by stevegee58 · · Score: 1

    Let's face it: How much new code have you really written over the course of your career? Most of the code I've worked with is legacy and it's not going away.
    C and its slightly less unattractive cousin C++ are here to stay. Companies have too much money invested in their working code base to just wipe it away and start over with some new wiz-bangy language.

  105. Perl is for cookie; C is a sometimes language by tepples · · Score: 1

    For one thing, I thought most applications using HTTP cookies were written in a managed or dynamic language. The song should have gone like this:

    Perl is for cookie, that's good enough for me
    Java is for cookie, that's good enough for me
    Python is for cookie, that's good enough for me [In this line you may substitute Ruby or your favorite pet language]
    Oh, cookie cookie starts with PHP

    Besides, Cookie Monster has started to sing that a cookie is a "sometimes food". Does this mean C is a sometimes language?

  106. Quarter meg difference by tepples · · Score: 1

    For comparison I made up a pair of Hello World programs, one in C and one in C++. The C version compiled down to 3220 bytes (still outrageous), but the c++ version came in at a whopping 4876 bytes

    That's nothing. I saw a quarter megabyte difference between Hello World using <cstdio> and Hello World using <iostream> (and static GNU libstdc++) after stripping. But then the C++/<cstdio> and C/<stdio.h> versions had the same size in bytes.

  107. Re:because - by Truedat · · Score: 1

    However, the parent made a point using the tool of sarcasm, that there is a lot of animosity towards C out there. You see it really wasn't a mystery to him at all. On the other hand you made an interesting but tangential point about the intelligence of such people.

  108. Work fast vs. work well by davidwr · · Score: 1

    If you want to write code that lets you go from idea to executauble in a short period of time but you don't care about efficiency, use a tool that does most of the work for you and which protects you from most implementation mistakes. Java, .NET, and other library-rich, managed environments do this well.

    If you want control over how things really work, use a tool where YOU know the libraries' performance characteristics, where YOU know the tool's "managed-code" characteristics if any, and YOU have the ability to tune them to your liking.

    Yes, you can "be naive" in C and have severe performance bottlenecks when you call a library function that is a total performance mis-match to what the rest of your code does, but it's a lot easier to be naive in Java or .NET.

    --
    Knowledge is how to play a game, intelligence is how to win, wisdom is knowing what game to play.
  109. close, but not close enough by bzipitidoo · · Score: 1

    I wish C could get closer to the metal.

    Only way you can do a 3-way comparison is hope the compiler optimizes it into the code.

    Switch statements are another place you have to hope the compiler can optimize. For simple operations, it's easy enough to whip up a lookup table and not use switch at all, but if you need to call functions from the cases you're looking at using function pointers. Always takes me a fair amount of trial and error to get the syntax of a function pointer correct, and then it still might not work. Easier to forget it and let the compiler turn a switch statement into a series of comparisons.

    Multiple entry to functions is another feature that isn't readily available. You can inline functions, and the compiler might heed you, or might not. In any case, inline doesn't help with this problem, just the opposite if anything. With macros, you can kind of do it in source code, for clarity, but the compiler will generate separate functions, rather like template functions. The MNG library is a good example of code that could use multiple entry. Lot of functions that are identical except for the input parameters and first few lines. Mozilla kicked MNG out of Firefox for being too bloated. Multiple entry might have shrunk MNG enough to save it.

    C does have a GOTO statement, but it should be used only in very controlled situations. I've never tried using GOTOs to implement multiple entry. Don't need it to skip the initial check of a while loop since unlike some languages (*cough* python *cough*), C has a "do while" loop. Only used it to exit nested loops, and for that I prefer to wrap the loops in a function and use return.

    --
    Intellectual Property is a monopolistic, selfish, and defective concept. It is "tyranny over the mind of man"
  110. C doesn't have to be standalone... by Anonymous Coward · · Score: 0

    A lot of people here are, frankly, circlejerking about how much control and efficiency you get from using a language like C and how much more efficient and low level and such. May I remind you that a huge case for C can still be made even if you think it's impractical for a given project?

    Other languages like Python or Ruby can be extended using extensions written in C which can give you the level of control C has with the modern language features one may expect/desire from that of Python and Ruby. Additionally, extensions with these languages often have helper functions for many of its tasks (such as invoking the VM for certain things) which allows you to be more practical than writing something in C from scratch.

    From this perspective, one could say C is great not only because it's awesome as a low level language but integral in modern languages, as well.

  111. Re:because - by moderatorrater · · Score: 0

    You, sir, are a magnificent troll. The only question is whether that's your intent or not.

  112. MultiBoot binaries for GBA by tepples · · Score: 1

    If it did, it would probably be one of the later things to try and optimize.

    Consider a platform that has 256 KiB of 16-bit RAM for code and static data and 32 KiB of 32-bit RAM for BSS and stack. New programs are loaded through a serial port on the top of the device. Tens of millions of units of this device have been sold. After seeing Hello World take up 248 KiB out of 256 KiB already, would you still consider size-optimization at this phase premature?

    1. Re:MultiBoot binaries for GBA by serviscope_minor · · Score: 3, Insightful

      You've set up a massive straw man.

      Why on earth would the vendor's compiler for that platform provide a standard library with full support for disk based files, POSIX locales, and all sorts of other obscure features when the target is a tiny micro?

      The C and C++ standard library in glibc and libstdc++ are both huge to deal with a lot of odd stuff specific to general purpose POSIX class computers.

      You wouldn't use the stock gcc iostreams, or the stock glibc on an atmel.

      --
      SJW n. One who posts facts.
    2. Re:MultiBoot binaries for GBA by PaladinAlpha · · Score: 1

      Yes, because what he said was clearly "I always demand using iostreams on every single platform regardless of environment restrictions, and there's no such thing as a tradeoff."

  113. What's wrong with C by Dwedit · · Score: 1

    What's wrong with C is the function call conventions. Where a function needs the first few arguments placed into specific registers or the stack, and returns things in a specific way. This can be a performance bottleneck, because data needs to be moved around just to place it in the correct positions, and back again.

    So what optimizers to is inline the functions, so they can avoid all the rigid restrictions placed by calling conventions, and the performance problems that come with them.

    Sure, calling conventions provide a standardized way to deal with unknown functions that aren't in the same source file, but the biggest advantage of hand-coded ASM is that you don't necessarily need to use them.

    1. Re:What's wrong with C by Old+Wolf · · Score: 1

      What's wrong with C is the function call conventions. Where a function needs the first few arguments placed into specific registers or the stack, and returns things in a specific way. This can be a performance bottleneck, because data needs to be moved around just to place it in the correct positions, and back again.

      So what optimizers to is inline the functions, so they can avoid all the rigid restrictions placed by calling conventions, and the performance problems that come with them.

      Sure, calling conventions provide a standardized way to deal with unknown functions that aren't in the same source file, but the biggest advantage of hand-coded ASM is that you don't necessarily need to use them.

      None of those things are anything to do with C. As you say, if you need to publish a library then you have to confirm to some particular ABI, this is the same for any language. And if you don't then you don't.

  114. C Is Safe; It's Programmers That Aren't by reallocate · · Score: 1

    All languages are exercises in abstraction, some more than others. That's the very nature of a computer language. They all exist to translate human intentions into something that can run a very, very, very complicated machine.

    C is less of an abstraction than some other languages. That does not mean it is old fashioned or outdated.

    Arguments that C is unsafe or dangerous miss the point. It isn't the language that is not safe. It's the programmer. If a programmer writes unsafe code in C, that programmer does not know his or her craft well enough.

    If C was unsafe, Unix would not exist.

    --
    -- Slashdot: When Public Access TV Says "No"
  115. The C11 memory model by Anonymous Coward · · Score: 0

    Gotta love section 7.17 of the standard!

    Seriously though, the new concurrency features in C11 are pretty special. I love that they abstract both the effects of the memory architecture of the underlying machine AND the effects of compiler optimizations. Unfortunately, they allow weird and unintuitive behavior (7.17p15), and that makes writing correct libraries hard.

  116. Do you accept sweets from strangers? by Hognoxious · · Score: 1

    Don't use includes unless they're from a trusted source, then.

    Though in the example given, even without any documentation at all, a ten line noddy program would tell you the answer wouldn't it?

    --
    Confucius say, "Find worm in apple - bad. Find half a worm - worse."
  117. Re:because - by RabidTimmy · · Score: 1

    But I'd argue that it is still more complicated than need be, as determined that people don't remember it. Why not just make it "const modifies the thing that preceded it. Final". Or maybe more English-like where the adjective precedes the noun.

  118. And English is a crappy language too by DriedClexler · · Score: 1

    To paraphrase someone: There are better languages than C. There are also better languages than English. Unfortunately, the world has latched on to both.

    --
    Information theory is life. The rest is just the KL divergence.
  119. Re:because - by TwineLogic · · Score: 1

    You can't handle the truth.

  120. Re:because - by Anonymous Coward · · Score: 0

    It has little to do with knowledge. I have created processors our of logic gates and memory cells using various diode patterns. Repurposed those micro-controllers that most mice and keyboards use, which required learning the machine language to implement an assembler. Even with enough knowledge to fully explain how a computer works down to the circuitry level, I still hate C. I'll take the friendly syntax and debuggers of Java and C# any day over the cryptic syntax of C.

  121. Comment removed by account_deleted · · Score: 1

    Comment removed based on user account deletion

  122. At least C programmers pick up their own trash! by Anonymous Coward · · Score: 0

    What? You don't think *automatic* garbage collection is "Clunky"? Well I do!

    The premise with languages such as Java is that developer time is precious so the fact that Java is comparatively slow is "OK". Well there is a certain performance multiple where that is no longer true. When a thousand servers eating power in a data center can be replaced by ONE server, a little developer time is worthwhile.

  123. "What's so great about C is..." by DdJ · · Score: 1

    "C combines the power and performance of assembly language with the portability and ease-of-use of assembly language."

  124. Below average? by GPS+Pilot · · Score: 1

    about 50% of them are actually below average

    Actually, exactly 50% of them are below average.

    --
    That that is is that that that that is not is not.
    1. Re:Below average? by HornWumpus · · Score: 1

      Pendant is exactly wrong. Must sting. 50% below median. Even there you have fencepost issues.

      --
      John McAfee 'It was like that time I hired that Bangkok prostitute; to do my taxes, while I fucked my accountant'
    2. Re:Below average? by jellomizer · · Score: 1

      No. About 50% not exactly 50%. Because we can create cases where averages are not 50%

      for example.
      Programmer 1: Grade 95
      Programmer 2: Grade 5
      Programmer 3: Grade 86
      Programmer 4: Grade 75

      Average Grade is 65.25
      3 Programmers are above average (75%)
      1 Programmer is below average (25%)

      I have gave an example to disprove your theorem. So your theorem is false, and you are wrong.

      Normally as the sample size increases (We would expect people to fall under a normal distribution) we will see the number getting closer to 50% however the chance of actually getting exactly 50% is very slim.

      --
      If something is so important that you feel the need to post it on the internet... It probably isn't that important.
  125. is C++ better than C by Anonymous Coward · · Score: 0

    int C = 1;
    if(C++ > C)
        printf("C++ is not better than C");

  126. A lot of C Programmers are missing Objective-C by QX-Mat · · Score: 2

    Disclaimer: I'm an Objective C Programmer by day

    The LLVM compiler suite is tremendously powerful with Apple's billions advancing many select features, but key to it's success from a users prospective the core use of reference counted object graphs (of type 'id') and reflection (RTTI - via 'isa' and 'Class'). Obviously this means the entire language is dynamically typed at runtime, but with express qualification in 99% of the code you'll use there's absolutely no performance hit despite the ubiquity of the core object.

    I worry that many C programmers will remember RTTI was once considered an unportable disaster in C++ because of the the many differing implementations owing to a spec that left the implementation up to each compiler... Don't let this kind of talk scare you! Although objective, objc is contained to a well defined spec, single inheritance and nary a template in sight.

    I consider my programming work to be relatively easy. 50% of my ease comes from the object system above. The other 50% from the fast messaging system used in place of raw ADTs: In the objc world a nil object doesn't fault when messaged (in a C world dereferencing a NULL pointer, common if a struct fetching function fails and then passes NULL on failure) leads to all manner of crashes, or as seen recently, kernel exploits. The messaging system can even push around primitive values, not just nasty objects.

    If you program in C, you may have missed Automatic Reference Counting, if you have, low and behold, it's amazing: at *compile time* the compiler adds lifetime qualifiers to the IR that automatically inserts retain and release messages (retain is +1 on alloc, -1 on dealloc - release occurs at 0). In other words the lifetime of an object in objective-c is now exactly the period of acquisition to last use. Yes, last use. ARC's use of a new 'weak' reference means that dangling pointers are a thing of the past: a __weak object is automatically nil'ed after last use: in all local instances of that object (did I say nil objects don't fault on message?).

    Admittedly most of what I've mentioned is thanks to the advances in LLVM's Clang compiler, in particular it's static analyser, therefore much objc analysis also benefits C (LLVM's IR is quite specular ).

    I could go on: methods can be heap objects with cblocks, objc encourages abstract programming with delegates, you can method swizzle at runtime, extend existing classes and link to C/C++ code.

    1. Re:A lot of C Programmers are missing Objective-C by Patman64 · · Score: 1

      Nope, haven't you heard, Objective-C is like, slow and junk, so obviously it's useless. Slow languages should be banned. It's also maintained by Apple, so obviously it's pure evil. If you were a Real Programmer (TM) you would use C++ because it's super fast and because you can't write games in a slow language amirite?

      Am I in the Slashdot cool programmer's club yet? Do I have to bash Java and talk about how great C# is too?

      In seriousness, objc is a fantastic language. The message dispatch slowness is vastly overstated, and compared to the amount of flexibility you get, when performance isn't critical, it is well worth it.

    2. Re:A lot of C Programmers are missing Objective-C by Anonymous Coward · · Score: 0

      And yet LLVM is written in C++.

    3. Re:A lot of C Programmers are missing Objective-C by Anonymous Coward · · Score: 0

      Objective C is worse than pre K&R C. It is a language plagued by an abortion of "SmallTalk" in square brackets and a no ansi C with no ability for passing by reference. There is also a confusion between C++ and C here. C as a cross platform assembler is very good. C++ allows for to0 many styles of programming and thus no C++ programmer writes programs in the same way. *There are too many ways to almost do the same thing the right way.*

  127. Re:because - by Livius · · Score: 1

    It's quite a bit simpler than that. * associates right to left, most other things left to right. const is just an innocent victim.

  128. Re:because - by turgid · · Score: 1

    You are today's winner!

  129. Ah yes 'C' by certsoft · · Score: 1

    Pascal's retarded cousin. The bane of my life but unfortunately it's normally the only language available for micro-controllers.

  130. Not slower in practice by Anonymous Coward · · Score: 0

    Show some realistic benchmarks or don't bother posting nonsense.

  131. Re:because - by FrootLoops · · Score: 1, Flamebait

    Those ignorant fools probably need to get off your lawn too, eh :)?

    I've programmed in assembly and C. I lack the patience to build a computer out of logic chips, but I've at least designed some stuff in logic gates. I've also implemented hash tables. Yet I still don't particularly like C, mostly because I find the syntax clunky. Specifically...

      * Semi-colon line endings are stupid--they serve little purpose besides making compilers easier to write
      * for (...;...;...) syntax is less intuitive than eg. VB.NET's "for a = 1 to 10" or numerous alternatives
      * declarations are unintuitive (and complicated; see post above for example)
      * I'm not fond of curly braces--I like Python's indentation better
      * Why make logical operators symbols instead of words?
      * operator precedence can be unintuitive
      * = vs. == causes bugs (many languages have the same trouble though)
      * comments (//) use two characters instead of one
      * switch's use of break is worse than eg. Ruby's case statement with commas

    (I have other issues, like disliking how many mundane details you have to specify in C compared to other languages, but you need a language like C for certain tasks and it'll need lots of mundane details to translate almost directly into assembly anyway.)

  132. It interfaces with 'C' code by Anonymous Coward · · Score: 0

    One of 'C's strengths is that it can talk to the APIs that have been developed in 'C', like all operating system APIs. I am only aware of 3 languages that can do this, 'C', 'C++' and Objective C. Everything else needs some kind of (binding/wrapper). As far as I know there is no language that has a wrapper interface that wraps the entire Windows API, not even C#. I know that most languages say it is easy to call 'C', but in many ways this is a lie. Python ctypes makes it quite easy to call 'C'. But when you a have a function that takes a large nested structure, it can still be a large pain to type all the declarations. And some 10 or 15 years ago I read that the Windows API had over 100,000 functions. It probably has a million today, but it is really the structures that the functions take that create all the work. I am not sure why this can't be automated, but to my knowledge it never has been. And then it seems that most wrapper libraries, like to slightly change the interface to make it easier to work with. For example, 'C' usually only returns an error code, and any other returns are via pointers past to the function. With a Python wrapper though, the wrapper will often times return multiple values. This coupled with weak documentation of the wrapper interface, and you are never sure what the interface looks like. This wrapper problem is one of the greatest weaknesses in all of programming. All languages suffer from this.

    On another topic. I was just thinking about the JVM today. It is my understanding the benefits of a virtual machine benefits are 1) easier porting 2) easier code generation 3) easier code distribution 4) potential for JIT producing faster code. Perhaps there are others. I am not sure if any of the reasons 1-4 are actually true or if easier is really that much easier. I am thinking that perhaps VMs are a mistake when it comes to distribution. VMs are great for development with a REPL. The JVM also lacks the proper support for dynamic languages and tail-call elimination. I know Python runs on the JVM with Jython, but it is much slower than Cython due to this lack of proper support. So the JVM is a massive memory hog and doesn't properly support dynamic languages or functional languages. The CLR is not much better. I just don't quite get it I guess.

  133. Re:because - by Anonymous Coward · · Score: 0

    In other words, the animosity comes from those who aren't qualified to judge.

    I salute you Sir. I couldn't have put it better myself.

  134. Re:because - by Iniamyen · · Score: 1

    Good to know you were hiring programmers, and not engineers, using this relatively pointless gotcha.

  135. Re:because - by scobiej · · Score: 1

    And I really didn't mean to post anonymously :) Thankfully, I know my C a lot better.

  136. Re: C++ is not equal to C by Anonymous Coward · · Score: 0

    This is wrong. == is not a sequence point and the result of C++ == C is undefined.

  137. Re:because - by Anonymous Coward · · Score: 0

    Can slashdot make an exception here and allow the above post to get to +6 or even +7?

  138. Comment removed by account_deleted · · Score: 1

    Comment removed based on user account deletion

  139. What's to love... by Gugliandalf · · Score: 1

    C has the raw power of assembler and can have the sleek elegance of Pascal. Period. What else can you possibly wish from a procedural language? And, yes. I learned assembler (Z80, on Sinclairs) before I learned C. Nowadays, I often teach programming languages, and strongly believe that C (and maybe a little assembler) should be a mandatory learning step under each programmer's belt. I prefer coding in OO langs,but when you need to get your hands dirty, C. Period. :)

  140. Re:because - by garyebickford · · Score: 1

    So, do you build your own carburetors? How often do you regrind the gears in your car's transmission?

    The above may seem silly (and not meaning to incite), but your argument is essentially that anyone who can't build a model T in their garage is incompetent to drive a car.

    Considering that a modern microprocessor has on the order of 2 billion transistors with many capabilities that used to defined by simple compilers and operating systems such as memory management, multiprocessor scheduling, programming for such machinery is a far cry from programming a 6800 - itself a bit past the usual assemblage of 7400-series chips. Compilers, linkers and future program generation systems must handle the complexities, which are already well beyond any individual programmer's capabilities to write optimal code for, just as modern fuel injection systems provide much better engine control than any carburetor, much less any manual spark-gap and fuel mixture control. It might be fun and entertaining to adjust the fuel mixture on your Model T as you drive in the parade, but it is not appropriate for driving a car with maximum efficiency on the freeway and in town.

    Continuing to use what has been described as a 'structured PDP-11 macro-assembler' for general purpose applications programming is like driving a Model T on the turnpike. And it's arguable that even for embedded use an AI-based program generator should by now be able to optimize better than almost every human programmer in nearly every case. If not, then that area of research is overdue for deeper study.

    --
    It's easier to be a result of the past, but more fun to be a cause of the future! http://www.spacefinancegroup.com/
  141. C haters don't matter by OrangeTide · · Score: 1

    We only care about the opinions of real programmers.
    If you aren't a C programmer then your opinion of C doesn't count.

    --
    “Common sense is not so common.” — Voltaire
  142. C is the best. by Anonymous Coward · · Score: 0

    If you can't use C safely then you're an amateur. C is far more powerful and useful than managed programming languages. I find it hard to believe that people find C clunky yet somehow manage to find shit like javascript or C# perfectly acceptable. What awful languages those are, yet people hate on C. C is the cleanest most beautiful and simple language that anyone has ever created. I don't know where anyone would get the idea that C isn't popular. It's been one of the top 5 most used programming languages for decades, and it has remained so for a reason.

    Don't hate on C just because you're an amateur who sucks at programming.

  143. Re:because - by Anonymous Coward · · Score: 0

    Well it is also the hardware-level language of choice. You can't write and OS in C++ that I know of without first defining the new and delete keywords, which mean you have to use the C malloc and free as a simple, base implementation. So even if you try to avoid it, you are still using it somewhat. It also operates very closely to hardware making it as efficient as possible (well I guess its up to the programmer how efficient it is)

  144. 'C' isn't less safe than Java by drew_eckhardt · · Score: 1

    Although the failure modes differ, 'C' and its interactions with its typical user isn't less safe than Java.

    'C' programmers know that they need to free their resources and make a habbit of it. Half decent ones even use a naming convention which implies dynamic allocation (ex: message_alloc) and suggests that code readers remember to apply a corresponding function when they're done (message_free).

    Java programmers generally assume that their resources will be garbage collected soon enough. While often true for memory, failures involving non-memory objects like file descriptors are not uncommon.

    'C' programmers almost never use a goto to get out of the middle of a function. Java programmers both do so regularly (in the form of exceptions) and neglect to catch/cleanup non-memory resources/rethrow.

  145. Re:Think of it as standardized assembly programmin by Kjella · · Score: 1

    I'm sure there's going to be a niche for that, but "embedded" like my CS professor used to call it was anything that was smaller than a laptop, like say my cell phone. Today my cell phone has 512MB of RAM and absolutely nobody wants "standardized assembly programming" for that. So if you exclude everyone that's into desktop, mobile or server software, the market for C programmers should be a small niche full of people making washing machines, microwaves, traffic lights and the like. Instead C is still being used a for a ton of high-level software. I think mainly because C# is controlled by Microsoft and Java has had it's own reasons, not because C is the best tool for the job. I like C++/Qt because Qt takes a lot of the C++ fiddling out of it, but I'd love to see something better.

    --
    Live today, because you never know what tomorrow brings
  146. c is a work horse by jamej · · Score: 1

    me like C

  147. Re:because - by zaft · · Score: 1

    Not a good analogy. Driving a car is more analogous to using a program than to writing one. So perhaps a better analogy would be anyone who can't build a model T in their garage is incompetent to be a mechanic. While that's overkill, there's some basic truth there. My experience is that people who didn't grow up on assembler and/or C have a very fuzzy idea as to what a pointer is, and often as to what a stack is or a memory space. It's particularly bad with people who learned Java as a first language.

  148. Re:because - by tzanger · · Score: 4, Insightful

    No, we stick with C because it is a great middle ground between assembly and high level languages. I would not want to write Python or Java on little microcontrollers. C is a small enough language that lets you write complex code relatively easily while staying close to the hardware.

    C's got its warts, it's true. It's a mature language that leaves the programmer in control of the system. It's not supposed to do the fancy things such as garbage collection, object management and so on. I'm glad it doesn't. There are other languages for that.

  149. Because assembly is a pain by Yvanhoe · · Score: 1

    C is useful when you want a compiler that optimizes your code but not so much that you can't control what happens on the byte scale. Nowadays, it is mainly for drivers and embedded software. C is a bit harder to use, but fast, small, concise, and close to the hardware will still keeping a decent amount of portability.

    --
    The Wise adapts himself to the world. The Fool adapts the world to himself. Therefore, all progress depends on the Fool.
  150. Reverted to C by buserror · · Score: 2

    I did C++ for a very, very long time (20+ years), and yes, you can take a nice subset of c++ that is not bloated, and in that case it's a nice language.

    The problem is when you work with other people. They'll drag in all the bloat they can, templates, RTTI, stl (ick), and... boost (arrrgh). And you end up with code that is actually giganormous, and runs slower than Java. I'm not joking, try stuff like OpenSCAD (chokes on 2 pages of geometry) or Code::Blocks (lags like crazy when editing the smalest of file) then there is the obvious KDE desktop, and many others.

    So a few years back I reverted to C99. C99 actually had some features that c++ lacks (complex struct initialisation for example) and after years of C++ you know enough about putting structure into your code that you don't /strictly/ need classes anyway. In fact, after a while, you start to realize that in many case, you /don't/ need classes -- sometime you can reduce a problem to 2 or 3 functions, you don't need the 24 accessors, 5 constructors and all that fluff.

    It's very refreshing try it. I think you can pick up good habits by hacking on the linux kernel and stuff like qemu/kvm... that sort of C project uses very complex constructs, all in C, and all in a 'clean' environment, there is a LOT to learn in these projects.

    The only thing I miss is references; thats the ONE thing I'd like to bring back.

    Oh, and if you want slightly smarter memory management for struct-like-objects and that sort of stuff, do lookup "libtalloc" -- it's a little bit of samba that is well worth the look at..

  151. Re:because - by garyebickford · · Score: 1

    I still like my analogy. For most of the programming I do, the problem I am solving can best be viewed as exploring an unknown space (the logical space within which the problem resides), looking for a reasonably efficient, reliable and repeatable path to the desired solution locus. I may incorporate a wide variety of mechanisms, even sometimes including running shell programs or database queries via ssh on remote machines. This could all be theoretically done by writing everything in C, but there is no reason - especially considering that the environments that I am working with may change radically without notice, so the entire application has to be restructured as fast as possible. Using dynamic languages is certainly in this case the correct solution (I won't go into which one is best.)

    So for me, the mechanicing is just part of the navigational problem - deciding which wrench to use and so forth.

    Having been in this business now since the days when most computer graphics programs were written in FORTRAN, (my very first language was ALGOL 68) IMHO even such things as device drivers are also easily viewed in this navigational paradigm. As an interesting example, the old Burroughs mainframes and operating systems were first built (together) entirely in software, using mostly formal methods. Then the parts of the system that required the most speed were implemented in hardware. Thus the 'mechanicing' was really just part of the navigation. (However there is the black art of micro-coding, where the timing idiosyncracies require a bit of 'creative destruction' on the formal model.)

    The mostly-dynamic languages I use, in fairness, are all largely themselves written in C so could be considered mere C applications, in the purest sense - the compilers or interpreters of few modern languages are themselves written in the target language as the original C was. But regardless, for nearly all programming tasks, even so-called 'bare iron' problems of interfacing to strange hardware, a well-defined model of the hardware and of the problem should be enough for a smart 'compiler' (for lack of a better term) should be able to figure out how to build the driver with little or no 'memory pokery' by a programmer. The fact that C programming is still widespread is a testament to the insufficiency of our tools.

    --
    It's easier to be a result of the past, but more fun to be a cause of the future! http://www.spacefinancegroup.com/
  152. Animosity vs Popularity and Hardness by tokiko · · Score: 1

    Although a number of things contribute, the popularity of a language certainly increases a perceived animosity. Heck, look at PHP.

    And, for those two languages, the ability of the user to shoot themselves in the foot probably doesn't help either.

  153. Re:because - by Anonymous Coward · · Score: 0

    How much of the laws of physics do you need to know to operate an hammer?

  154. amusing by spoony1971 · · Score: 1

    amusing. C & lisp are the best languages available currently. Sooner or later, a developer will become to love them as long as they do not quit programming job.

  155. Re:because - by FrootLoops · · Score: 1

    Uh, why did I get modded flamebait?

  156. C unsafe by hackus · · Score: 2

    Yes, and like firearms, you need training and instruction before use.

    C like firearms, requires training and instruction before use.

    I wouldn't put a firearm in the hands of a 6 year old, a politician or a banker because obviously the 6 year old will hurt themselves and the politician and banker will give it too someone else to shoot you with. (or...quite possibly the attorney general would just ship it to mexico and have drug gangs kill you....but I digress.)

    Likewise, I would not give a C compiler to a asp programmer or visual basic programmer. The asp programmer would crash the server, and the visual basic programmer would unwittingly put back doors in the software they write to which they would exclaim:

    "Jeepers, how did that happen?"

    -Hack

    --
    Got Geometrodynamics? Awe, too hard to figure out? Too bad.
  157. Re:because - by Anonymous Coward · · Score: 0

    Yes sir, sorry sir, getting off of your lawn now sir.

  158. Re:because - by luis_a_espinal · · Score: 1

    And the funny thing is that most people who write const char* foo really want char const * const foo. You don't want either the pointer or the data pointed at to change. However, almost nobody knows that, so even those who do just use the weaker const char* so people understand the code.

    Hmm. I wonder why there's so much animosity towards C? It's a mystery.

    Because they don't RTFM? I mean, c'mon, the rules of reading type C declarations have existed for, like, what, 40 years already.

  159. Re:because - by Anonymous Coward · · Score: 0

    The small amount of coding that I've done in C really changed the way that I looked at solving problems. You don't necessarily have to master C, but having some exposure to C, assembly or something else low level really helps one understanding what they're asking the computer to do.

  160. Re:because - by luis_a_espinal · · Score: 1

    And the funny thing is that most people who write const char* foo really want char const * const foo. You don't want either the pointer or the data pointed at to change. However, almost nobody knows that, so even those who do just use the weaker const char* so people understand the code.

    Sometimes it depends on the situation (typically for performance reasons) when you do not want that. I might want a const char* (yeah, I prefer to put the const on the left side of the type when declaring a pointer to const).

    And I might want it to point to something const... but that something is still not available, or it might change over time. Yep, the const doesn't necessarily denote const'ness for the duration of the execution (though it usually means that.) It simply means that the compiler agrees to treat that which it points as read-only, from the point of view of the observer, at that moment in time.

    One good example are the CORBA::Any extractor operators as found in the CORBA-to-C++ mapping (mind you that this is not longer just C, but C++. However, the concept still applies.)

    The CORBA::Any extractors contain the following operator signature:

    Boolean operator>>==(const CORBA::Any& any, const char*&)

    It takes a reference to a pointer to const. It modifies the pointer to const so that it points to an internal, read-only buffer for performance purposes. Should the caller decided to make changes, he/she then creates a duplicate.

    And although this is C++, the same can be done with a (const char*)*. Certainly that this can be abused with horrific results, but that is one beautiful thing, that the language allows you such a construct (should you have a valid reason.) At the end of the day, the onus must always reside on the programmer. His success or fuck up should be his and only his, not the compiler or language.

    Beyond this specific niche scenario, I generally do not do const-pointer-to-const because the extra step does not add me any extra security that cannot be obtained by simple coding conventions. I simply settle with pointer-to-const.Not that I'm saying the extra benefit you claim is non-existent, but I simply do not think it is a great advantage either.

    I would even say that, the practice is not common (can't recall ever seeing a POSIX function with a const-pointer-to-const, but I recall many with pointer-to-const). And since the practice is not common, if I were to see it in the wild, I would assume there is something specific in the design, or algorithm, that requires the pointer to remain const as well, else here be dragons. I would have to spend extra time (perhaps very little, perhaps a very fucking lot) to determine if the const'ness in the pointer is actually critical for the execution of the algorithm under review.

    That is, for me, the code should say no more or no less than what it is functionally required to do.

    YMMV of course since I cannot claim my POV is devoid of subjectivity.

  161. How far how fast by tepples · · Score: 1
    Different people apply different tradeoffs at different levels of pain. I just wondered at what point a tradeoff would be needed, and what tradeoff one would try first. One could abandon <iostream> early, or one could continue to use it while looking for ways to strip as much unused code as possible. I can think of several steps:
    • Linking with -Wl,--gc-sections got it down to 176 KiB
    • One could modify libstdc++ to dummy out locales
    • One could switch to uClibc++, which is premature-optimized for size, with some standard features missing that are deemed unimportant for embedded
    • Give up and switch to <cstdio>

    How far how fast was what I wondered.

    1. Re:How far how fast by PaladinAlpha · · Score: 1

      If you're pursuing honest discussion, I apologize for the snark.

      Generally, on limited (embedded) platforms, the functionality exposed by iostreams isn't needed, as there's no stdio, and no real buffering to speak of. In such situations you'd still get mileage out of STL containers (possibly with a custom allocator), which carry negligible size implications, but not really any of the heavyweight stuff like streaming.

      I'm not a huge fan of iostreams myself, but they're worth using for the type safety, and if you can afford a printf call you can typically afford the 250k link.

  162. Re:because - by luis_a_espinal · · Score: 1

    Thank you. "const" modifies the thing that preceded it. Iff nothing precedes it, it modifies the first thing that follows it. It's not terribly complicated.

    It is for the garbage-collector-pampered crowd :)

  163. Re:Think of it as standardized assembly programmin by Honclfibr · · Score: 1

    Doesn't have to be that old. I wrote, and am still maintaining a program written for an MSP430 that fits into 13k (ok, 12.8k) of code, as it was a 16k part and 3k was used for the bootloader + vector table. It's running right now, controlling power supplies and running PID loops. Actually, it's running about 750,000 copies right now, 24 hours a day, 365 days a year. Which is why it had to fit into 16k. Every penny counts when you multiply times 3/4 million. And yes, of course it's in C. No worries about memory leaks though, there's no heap. I do worry about the 80 byte stack though, maybe it's time to bump it up to an even 128.

  164. Scientific Computing? by barlevg · · Score: 2

    500+ comments and nothing about the fact that in academia, most code that's written for speed (still waiting on that MATLAB code to finish...) is written in either C or FORTRAN? I must have missed something.

  165. Re:because - by Pseudonym · · Score: 1

    Sometimes. But let's be honest- how many times when you write const char* foo="some string" do you really want that?

    Enough times that I've lost count. You probably have too, you just don't realise it.

    How many times have you written code like this?

    const char* markText = "";
    unsigned value = data.unmarkedValue;
    if (data.flags & MARK)
    {
            value = data.markedValue;
            markText = " (marked)";
    }
    printf(" %d%s\n", value, markText);

    --
    sub f{($f)=@_;print"$f(q{$f});";}f(q{sub f{($f)=@_;print"$f(q{$f});";}f});
  166. Re:because - by russotto · · Score: 1

    And the funny thing is that most people who write const char* foo really want char const * const foo.

    Actually, you usually want
    const char foo[] = "some-literal";

    The subtle difference being the behavior of &foo. Why waste any space (even read-only space) for the pointer?

  167. Wow by Murdoch5 · · Score: 1

    "Antiquated, clunky, and unsafe"

    I really hope who ever wrote this isn't a programmer. C is only unsafe when you don't understand how memory works and if you don't understand how memory works you shouldn't be programming. C is only clunky at the hands of an unskilled and amateur programmer who doesn't understand good coding methods and antiquated, well just show me one other language besides ASM that can holds it's own and keep going.

    I know someone will try to talk about how OO programming is where it's at and managed code = better code and all that BS, OO languages were invented because people had no F'ing clue on how to write good software. If you can't write it in C then go back and try again. Managed code is the biggest slap in the face because it's extracting the programmer from clean programming. If you honestly want to claim that managed code or OO code is better then good old C then do me a favour and NEVER program again because I can promise you that the crap you input to an IDE is so poorly structured and programmed it should be used for house mats and not actual hardware.

  168. Re:because - by jedwidz · · Score: 1

    Function arguments are an awkward case: the extra 'const' becomes part of the function signature, even though it's irrelevant to the caller. It's understandable (and idiomatic) to spare an API user the distraction.

    The purist in me would like a language feature for declaring stronger const-ness of an argument within the function body.

    Likewise for Java ('final' keywords in public method signatures).

  169. Re:because - by Anonymous Coward · · Score: 0

    Because:
    * making compilers easier to write generally has the side-effect of making them faster. C is supposed to be small a lightweight, and this goes for the toolchain too.
    * for(;;) is much more flexible than for ... to ..... One can iterate using all kinds of conditions, numeric range is a special case really.
    * Most people seem fine about them. How intuitive does a language need to be. One is always going to have to *learn* it.
    * Python indentation is painful beyond belief. C has it right in this respect. Whitespace is *invisible*. Thus your program may be *invisibly* wrong. This is bad.
    * Because they take fewer characters (a point you argue for slightly later on) and are easier to read
    * It's a bit arbitrary, as it is in many languages with lots of different operators. Use brackets
    * only for idiots.
    * This is fine. Original C used /* .. and */ anyway, and that's four characters! '//' is an improvement.
    * No idea what you're on about here. Maybe you're even right, although if the above is anything to go by I doubt it.

  170. Wanting to abandon C: It's not about control by hythlodayr · · Score: 1

    Don't get me wrong, I think C will have a very long and robust life: It's the one and only bootstrap language of choice offered by just about every OS and CPU maker. And I think that it's too bad.

    Many of the reasons for wanting to discard C have nothing to do with the low-levelness of C. Dependencies in C are a nightmare to trace, and probably bloats compile times by a tremendous amount. Then there are deadly designs such as C-strings and even worse inconsistencies within the string functions (think null terminator).

    A better-designed system language is certainly possible (e.g., Google Go which is dying a slow death,) and it wouldn't be the worst thing to happen if it were to catch on.

    1. Re:Wanting to abandon C: It's not about control by JDG1980 · · Score: 1

      Then there are deadly designs such as C-strings and even worse inconsistencies within the string functions (think null terminator).

      There is no such thing as a string in C. There are standard library functions that let you pretend there is, but neither the language nor the compiler know the semantics of these. As far as the language itself is concerned, it's all just pointers to memory.

    2. Re:Wanting to abandon C: It's not about control by Anonymous Coward · · Score: 0

      There is no such thing as a string in C. There are standard library functions that let you pretend there is, but neither the language nor the compiler know the semantics of these. As far as the language itself is concerned, it's all just pointers to memory.

      Sort of right. Strings in C are just arrays (they have a type of char array) but the compiler *does* have to know about them to interpret string literals in the code.

    3. Re:Wanting to abandon C: It's not about control by hythlodayr · · Score: 1

      Sure there is: If a block of memory doesn't contain a null-terminator--as expected by the library functions--then the item in question isn't a c string. If you're saying C-strings don't exist because it's purely a standard-library concept, then we'll still have to disagree: The standard libraries make the language as much as the syntax and base-types, and this is even more true for established languages.

    4. Re:Wanting to abandon C: It's not about control by JDG1980 · · Score: 1

      Sure there is: If a block of memory doesn't contain a null-terminator--as expected by the library functions--then the item in question isn't a c string. If you're saying C-strings don't exist because it's purely a standard-library concept, then we'll still have to disagree: The standard libraries make the language as much as the syntax and base-types, and this is even more true for established languages.

      It depends on how you define a string. Sure, you can refer to a null-terminated character array in C as a string. But it doesn't contain the features you see in languages that have strings as a ground-up, first-class concept. You can't concatentate with the standard "+" operator (you have to use strcat or its equivalents) and more importantly there is no built-in protection against buffer overflow or other such issues. This is why I made my original statement: if you start thinking that C's null-terminated character arrays are "strings" in the high-level language sense of the term, you will get too complacent and get bitten by errors and security vulnerabilities.

    5. Re:Wanting to abandon C: It's not about control by Anonymous Coward · · Score: 0

      It depends on how you define a string. Sure, you can refer to a null-terminated character array in C as a string. But it doesn't contain the features you see in languages that have strings as a ground-up, first-class concept.

      This is correct, but it's overstating the situation to say "strings don't exist in C." They may not be a distinct data type, but they are very much part of the language and its libraries.

      Case in point: the existence of <string.h> and any chapter on "strings" in a a C text.

  171. Re:because - by mrchaotica · · Score: 1

    I like C. I also drive a car with a manual transmission, and change my own oil, spark plugs, and brake pads.

    Regrinding transmission gears or building carburetors is like programming in assembler (or maybe even writing machine code with a hex editor).

    However, that's not to say that I don't also like high-level languages. I especially like C# for the clean object-orientation, plus the syntactic sugar (e.g. accessor methods) and operator overloading that Java doesn't have (not a fan of the Microsoftness, though). MATLAB/Octave is really convenient for mathematical stuff, too.

    --

    "[Regarding the 'cloud,'] ownership was what made America different than Russia." -- Woz

  172. Re:because - by Anonymous Coward · · Score: 0

    Just use const char foo[] = "" instead of const char * const foo = ""

  173. get off my lawn by Tom · · Score: 2

    That article could've only been written by someone who isn't a coder. If you are a coder and you can't code C then you aren't a coder. Seriously.

    C is a great language. It's the AK47 of programming languages - rough, barebones, you definitely need to know how to handle one because it doesn't do all the handholding for you, but you can drop it in the mud, drive a tank over it, pick it up and fire it - and it will fire. None of that 10,000 library dependencies crap.

    Learning to code in C - and I don't mean "hello world", I mean a real program with input validation, safe pointer handling and your own memory management - puts you in a great position to write good code in every other programming language.

    Basically, people who don't know C are doomed to repeat the same old mistakes. The problem is that most other languages are a lot more forgiving. And thus your errors don't get noticed so easily, until they've accumulated to create a security issue. In C, if your memory handling sucks, you get a buffer overflow and often a hard crash. If you don't handle your input correctly - crash. And so on.

    Back at university, when I was the assistent for the C programming course, students hated me for the 100 ways I could make their precious little programs crash. But those who got their code past me had learnt to write safe code, and I'm taking bets that they still do so today.

    --
    Assorted stuff I do sometimes: Lemuria.org
  174. extern "FORTRAN" by Anonymous Coward · · Score: 0

    With multidimensional variadic array support redeclared as optional in the latest standard, and with array function parameters, which should be restrict pointers by default in array syntax, not even accepting restrict modifiers unless declared with pointer syntax (very hard to get right when multidimensional arrays come into play), and with C++ poo-pooing native arrays anyway, C is ready for another 50 years of extern "FORTRAN" for reasonably optimizable numerical code that does not has library-unique storage and calling conventions.

    Congrats for an amazing streak of consistency.

  175. C is great by terminal.dk · · Score: 1

    My C code works fine in C, C++, Objective C etc.
    C is the base for all portable code, unless you want something like Java, which I am skilled in, but never really liked. I prefer Perl og java any day. But yet, much of the syntax is the same, no matter which one of these languages you use. They are all C-like to some degree.

  176. Re:because - by FrootLoops · · Score: 1

    Your "Because" is silly--merely being wrong (which I was not) does not make for flamebait. You have to try to get others to flame you. If anything you seem to be trolling, but if not...
      * Not always, and not in the case mentioned (which you didn't even discuss specifically).
      * VB.NET uses for ... to ... [step ...], which could easily serve the same purpose with the same flexibility, and it's incredibly easy to imagine similar syntax with the same power as the C version. You're just trying to contradict me here.
      * I disagree, and the example I referred to is +5 informative right now.
      * Whitespace is not invisible--it is visible in the spacing of other visible text. Your reasoning here is poor, though I know this issue is largely a matter of taste and I was only (and clearly) stating mine.
      * They take fewer characters, which is nice, but can you honestly tell me "not (a and b) or not c" is easier to read than "!(a && b) || !c"? [Note: I'm not sure if I got the precedence rules right and I won't look them up.]
      * No. There are honestly broken precedence rules, K and/or R has mentioned it; I can hunt for the reference if you want.
      * Again, no. It's an easy mistake to make once in a while. It's also easy to miss when debugging and can cause strange errors.
      * This was a minor point, but still, your reasoning is poor: "C used to be worse, so you should be happy about the current situation because it's not even worse!" I'm generally fine with it too, though I slightly prefer single comment "characters".
      * An example:

    C-style:

    switch(i)
    {
            case -1:
                    ++i;
            case 0:
                    ++i;
            default:
                    ++j;
    }

    Forgetting the break's results in completely wrong behavior, but the first two cases should be combined into one, which break is useful for:

    switch(i)
    {
            case -1:
            case 0:
                    ++i;
                    break;
            default:
                    ++j;
    }

    And does one include "break" in the last case? Does it matter? (No.) Ruby offers similar functionality that's more intuitive and less error prone:

    case i
    when -1, 0
            i += 1
    else
            j += 1
    end

    (The Ruby version is more powerful, actually, since i can be anything and the === methods are used for comparison.) The C version is another example of easy-to-compile-but-harder-to-read-and-potentially-bug-causing syntax, though it translates almost directly into assembly. The Ruby code is slightly (only slightly) more difficult to interpret yet is better in several ways--no clunky semicolons or colons, no break's, the multiple identical cases have one line instead of two keeping parallelism intact, there's no need to remember the "default" term (why wasn't "else" used originally anyway? another compiler hack?). Each individual issue is quite minor, but small things add up to make everything around us, and C is no different. Like I said, I dislike the clunky syntax. It was clearly made in the early years of programming and has been improved many times by many people in many ways. We seem to be stuck with it now though.

  177. Re:Think of it as standardized assembly programmin by Anonymous Coward · · Score: 0

    ..You use C because, assuming you understand the instruciton set, you can pretty much predict what assembly instructions it's going to generate and create very efficient code..

    If you truly understood the instruction set (and the target system board) then why would you be writing the code in C rather than assembly? Having spent (way too) many years programming in assembly and seeing/debugging the output code of various 'optimising' cross compilers I still don't 'get' the supposed benefits. The arguments about portability of the C code have been made since the start, the cynic in me always saw that as a means for the management to employ 'monkey' recent CSD graduates to do the code rather than the (more expensive) Engineering graduates with the requisite assembly language skills.

  178. Re:because - by stripes · · Score: 3, Interesting

    I think C's originators (or at least the still living one) changed his mind about some of them. From looking at the go language which targets the same programming niche some of these things have been addressed.

    The semicolons are implied in most places now (as a side effect it enforces a brace style many people dislike, but happens to be my preference -- so even though I'm happy with C's semicolons this is a borderline positive change for me).

    Declaration syntax has been made "more sane", which isn't surprising, and by the time K&R wrote the C book they had already started regretting it (one of the assignments was to parse C declarations into "english", look at what the authors wrote about it).

    Go revamped switch (and a lot of the control flow operators).

    Some of those changes might just be because computers have gotten a wee bit faster in the last 25 years or so, what constituted a great tradeoff on a computer with a 64K (split I+D) address space and maybe 512K max RAM a clock cycles measured in a few Mhz (oh, and these were multi user computers) is a wee bit different from what makes a good tradeoff now. (semicolons I think wind up here)

    Some are likely to be a change they would still have made on the original system. (most of the control flow changes wind up here, likely variable decl too)

  179. Go language by Frogg · · Score: 2

    I like C, and have used it a lot on and off over the years (and probably will still have to again, at some point) - but recently I've been totally loving programming in Google's Go language: it's just fricking awesome, for so many reasons! :)

    I think Go is destined for Good-Things(tm) in the future

  180. Re:Bad quiz: "implementation defined" not an optio by TheRaven64 · · Score: 1

    Please mod up. I found the quiz similarly irritating. Half of the questions say you got the answer wrong and then say that the person writing the questions was making assumptions that are not true in the general case and you are wrong for not making the same assumptions.

    --
    I am TheRaven on Soylent News
  181. Re:because - by Eraesr · · Score: 4, Interesting

    What a crock of shit. C is just a different tool for a different job.
    When writing business software for Windows desktop platforms you don't want to mess around with pointers, memory addresses or other relatively low level stuff like that. High level languages like Java, C#, heck, even Delphi are far more useful for that and allow for far greater productivity.
    Sure, there are situations where C is the better choice, just like even lower level languages are sometimes a better choice, but claiming that people choose Java, C# or Python over C because they're ignorant is ignorant in itself. If, these days, you choose to build your windows forms application in C, then you're just getting yourself in a world of hurt that could easily be avoided by choosing a different tool (programming language).

  182. he loves C by Anonymous Coward · · Score: 0

    "i love C, i can do anything i want." Yeah, right. Here is some more rope to hang yourself and write incomprehensible, unmaintainable and insecure code. And your mother wears Army boots.

  183. Re:because - by Anonymous Coward · · Score: 0

    Oh, hell, the majority of you you transistor-radio assembly types couldn't assemble a computer using vacuum tubes if your life depended on it. In my day, those with the least bit competence could do that no problem.

    It's no wonder that computer systems are so hard to use and inefficient these days compared to decades ago.

  184. Re:because - by theCoder · · Score: 1

    There is a big difference from the caller's point of view between foo(char*) and foo(const char*). The former allows modification of the string being passed while the latter does not. This can be important to the caller, and can mean the difference between calling foo("some string literal") and having to copy that literal into a character array to pass.

    You can make something more const in a method, if you really want:

    void foo(double d)
    {
      const double* const dPtr = &d;
     
    /* read "d" by accessing *dPtr */
      printf("d is %f\n", *dPtr);
    }

    If you're using c++, you can also use const references, which won't add any overhead (I don't think these have been added to the C spec, but I could be wrong):

    void foo(double d)
    {
      const double& dRef = d;
     
    // read "d" by accessing dRef
      std::cout << "d is " << dRef << std::endl;
    }

    I've done the const reference trick before when I've wanted to call the const overload of a method on a C++ class because I knew the non-const overload did extra work I didn't want it to do (because it was non-const).

    --
    "Save the whales, feed the hungry, free the mallocs" -- author unknown
  185. Re:because - by garyebickford · · Score: 1

    I like C. I also drive a car with a manual transmission, and change my own oil, spark plugs, and brake pads.

    Regrinding transmission gears or building carburetors is like programming in assembler (or maybe even writing machine code with a hex editor).

    However, that's not to say that I don't also like high-level languages. I especially like C# for the clean object-orientation, plus the syntactic sugar (e.g. accessor methods) and operator overloading that Java doesn't have (not a fan of the Microsoftness, though). MATLAB/Octave is really convenient for mathematical stuff, too.

    And I think that's a very good attitude. :)

    --
    It's easier to be a result of the past, but more fun to be a cause of the future! http://www.spacefinancegroup.com/
  186. Sig by burisch_research · · Score: 1

    I have one

    --
    char*f="char*f=%c%s%c;main(){printf(f,34,f,34);}";main(){printf(f,34,f,34);}
  187. Re:because - by Anonymous Coward · · Score: 0

    claiming that people choose Java, C# or Python over C because they're ignorant

    That's not what he said. The topic was where the animosity towards C comes from.

  188. Re:because - by Anonymous Coward · · Score: 0

    Do that Ruby switch statement with no line breaks, I want to see how well it works on one line.

  189. Re:because - by Anonymous Coward · · Score: 0

    It sounds like you do not work in the modern world of software development where the "hammer law" prevails. I only know how to use a hammer, therefore everything looks like a nail to me. Today developers only use the one language they know, regardless of the project. That is even enforced by the enterprise "standards". These developers do not know anything else therefore I agree they cannot evaluate the benefits or disadvantages of C.

  190. Re:because - by Anonymous Coward · · Score: 0

    > I only know how to use a hammer, therefore everything looks like a nail to me.

    The correct formulation for modern software developers is: "Given a sufficiently complex hammer, any problem can be modeled as a nail!"

  191. Re:because - by Anonymous Coward · · Score: 0

    I fail to see the point here... are you implying that Python is better for a business application that C is? That's odd considering the Python is relatively slow and resource intensive, and should you have a large number of users the application would likely not run well.

    Java has gotten better over the years, but I only really see Java as beneficial if I am in a mixed platform environment.

    How is C + GTK difficult? If you are a programmer, the language should largely not matter much to you.

  192. Re:because - by Jerom · · Score: 1

    I feel exactly the same about Scheme. Haven't done a lot in it for production use, but learning it has definitely made me a better programmer!

  193. Re:Bad quiz: "implementation defined" not an optio by tepples · · Score: 1

    Later I discovered that there were instructions before the quiz telling the user to assume the x86 and x86-64 ABIs. But I didn't knew this because after I had clicked begin, the instructions disappeared. And no, I'm not about to go buy an x86-64 PC just to complete a quiz that a Slashdot user linked.

  194. Re:because - by betterunixthanunix · · Score: 1

    I would not say that C is a "great" middle ground. Ambiguous statements are not a requisite of a small language. Allowing pointers to be used uninitialized is not a requisite either. Allowing a non-void function to have no return statements is also not a requisite. There is no legitimate reason for any of the above, they only create problems and make debugging harder. We should not be relying on compiler warnings (non-standard), we should have a language that does not allow us to do things that never make sense.

    --
    Palm trees and 8
  195. Abort, retry, fail by tepples · · Score: 1

    Generally there are two options when your allocator gives you NULL; that's either retry or abort

    Ideally, the program would free up some memory . But you mentioned "Abort" and "Retry" which make up two-thirds of an old MS-DOS-era meme, the third of which is "Fail". There is a way to "Fail" using C++ exceptions, and there is a way to "Fail" using result codes (which is what DOS did). "Fail", propagated up the call stack, would allow freeing up some purgeable resources so that the outer loop can "Retry" later. The other option would be to "Retry" immediately after purging some purgeable resources within the allocator, but I don't know how much latency that would introduce.

  196. Re:because - by Anonymous Coward · · Score: 0

    "Eraesr" thinks that TwineLogic claimed "people choose Java, C# or Python over C because they're ignorant". TwineLogic wrote nothing of the kind. TwineLogic wrote that ignorance (and "lack of ability") were the causes of the "animosity" towards C.

    This is not a crock of s---, but an absolutely correct assessment of "newer programmers", who actually aren't programmers, but merely configurators who escaped mastering the fundamentals of computer science, information systems and programming, precisely because they only learned to, not program, but script, really, in "high level languages like Java, C#..." and were never imposed upon to do real Pascal with Delphi.

    But true efficiencies in those high-level languages are best discovered by programmers fluent in fundamentals, and when things get mystifying in those high-level languages, "newer programmers" have little idea how to sort them out.

    Judging by their tone, and flat-footed comments such as "allow for far greater productivity" and "Sure, there are situations where C is the better choice...", "Eraesr" seems to be one of those "newer programmers".

  197. C is A+ by NikeHerc · · Score: 1

    I know nine programming languages, seven of them fluently. I also know the machine language of five different architectures, plus the microcode of a sixth architecture.

    C is the seventh high level language I learned. I've been coding in C since about 1987. For any serious work, C is my only choice.

    If you don't have the discipline or intellectual ability to code well and quickly in C and to produce code that is very nearly bug free on the first pass, you should go back to visual basic (or to other simpler languages) and leave the hard tasks to the pros.

    --
    Circle the wagons and fire inward. Entropy increases without bounds.
  198. Re:because - by EkriirkE · · Score: 1

    ...I still don't particularly like C, mostly because I find the syntax clunky. Specifically...

    * Semi-colon line endings are stupid--they serve little purpose besides making compilers easier to write

    It's more than just for stupid compilers, otherwise a newline would serve that purpose as it does in other languages. Sometimes I like writing multi-line single statements (e.g. a function call with huge parameter count) and not have to conversely write a special character to denote a line continuation after carriage return.

    * for (...;...;...) syntax is less intuitive than eg. VB.NET's "for a = 1 to 10" or numerous alternatives

    Perhaps if you limit "for" to linear iterations. I kind of prefer the "for (init;true;post) ..." format as a clearer "init;while(true){...;post;}"

    * declarations are unintuitive (and complicated; see post above for example)

    True, #define, typedef, standard declares mix me up sometimes.

    * I'm not fond of curly braces--I like Python's indentation better

    I'm with you on this, if you want everything on its own line.

    * Why make logical operators symbols instead of words?

    The same reason mathematical ones are symbols, I suppose. It was logical ;) Real-world match actually uses symbols for logic as well.

    * operator precedence can be unintuitive

    There is a PEMDAS going deeper to include logic. Use parenthesis to make it stupidly clear if unsure.

    * = vs. == causes bugs (many languages have the same trouble though)

    Only for those coming from different-styled languages. The = as both a value assign and zero/nonzero check has come in handy many times, and shortens code both visually and compiled.

    * comments (//) use two characters instead of one

    Can't argue that. C and SQL are the only langs I can think of with double commenters.

    * switch's use of break is worse than eg. Ruby's case statement with commas

    (I have other issues, like disliking how many mundane details you have to specify in C compared to other languages, but you need a language like C for certain tasks and it'll need lots of mundane details to translate almost directly into assembly anyway.)

    What's wrong with the break statement in switch? I like the comma listing cases over multiple stacked cases.

    --
    from 09 F9 11 02 9D 74 E3 5B D8 41 56 C5 63 56 88 C0
    to 45 2F 6E 40 3C DF 10 71 4E 41 DF AA 25 7D 31 3F
  199. Standard containers don't expect nothrow by tepples · · Score: 1

    From the page you linked: "This will likely fail fatally. Standard containers deal with memory using allocator (by default standard allocator) and at least one of them expects exception to be thrown when there is no memory and will not check for NULL return value." I mentioned that earlier.

  200. Re:because - by lsatenstein · · Score: 1

    And the funny thing is that most people who write const char* foo really want char const * const foo. You don't want either the pointer or the data pointed at to change. However, almost nobody knows that, so even those who do just use the weaker const char* so people understand the code.

    Hmm. I wonder why there's so much animosity towards C? It's a mystery.

    Animosity is there because programming in C requires a non-lazy mind, to understand side-effects and items your function will not cover.
    There is no framework as one finds with C++, Python, C## or other oo languages.

    --
    Leslie Satenstein Montreal Quebec Canada
  201. Re:because - by FrootLoops · · Score: 1

    Ok, here ya go:

    case i; when -1, 0; i += 1; else; j += 1; end

  202. Re:because - by FrootLoops · · Score: 1

    It's more than just for stupid compilers, otherwise a newline would serve that purpose as it does in other languages. Sometimes I like writing multi-line single statements (e.g. a function call with huge parameter count) and not have to conversely write a special character to denote a line continuation after carriage return.

    A lot of modern languages have implicit line continuations, like Ruby where if you end the line with some sort of operator (or comma) it's implicitly continued. It seems to work very well. (Conversely, a lot of modern languages have an "end of statement" character allowing you to put multiple statements on a single line--in Ruby it's the semi-colon.)

    * for (...;...;...) syntax is less intuitive than eg. VB.NET's "for a = 1 to 10" or numerous alternatives

    It seems I should have been clearer. VB.NET's full syntax is "for [var] = [bound] to [bound] step [num]", which could easily be hijacked to replace the C "for" syntax without any loss of power. Many languages also offer "for [object] in [array/tree/iteratable thingee]" syntax built-in, like Ruby, Python, and C#. There's lots of good one can do with good "for" syntax.

    [Question: Why make logical operators symbols instead of words?] The same reason mathematical ones are symbols, I suppose. It was logical ;) Real-world match actually uses symbols for logic as well.

    I'm actually a mathematician with a CS background. In math functions are traditionally denoted by a single symbol (eg. the gamma, theta, or zeta functions; f(x), g(x), h(x), etc. for arbitrary functions in proofs); the only exceptions I can think of are the trig functions, though most likely that was because the names hint at their relationships (eg. csc vs. sec: "co" means you swap the legs in the definition, so eg. sin = opp/hyp, cos = adj/hyp; co is the substitution opp <=> adj). In any case, things are different in computers where full names are allowed. Beyond tradition, making an obvious distinction between bitwise and logical boolean operators is laudable (when I get back to C-style I'm always slightly unsure at first if I should | or ||, for instance).

    There is a PEMDAS going deeper to include logic. Use parenthesis to make it stupidly clear if unsure.

    For instance, "x & 1 == 0" is actually "x & (1 == 0)" while one almost surely means "(x & 1) == 0".

    Only for those coming from different-styled languages. The = as both a value assign and zero/nonzero check has come in handy many times, and shortens code both visually and compiled.

    I agree it's useful. I just also say it causes bugs sometimes. I'm honestly not sure if there's an alternative I like; Python and Ruby both continue the C style. I maybe like "is" for "==" but I'm not sure....

    What's wrong with the break statement in switch? I like the comma listing cases over multiple stacked cases.

    I gave a more complete explanation at the end of this post.

  203. Re:because - by jedwidz · · Score: 1

    I did an experiment with gcc, and apparently the following is fine in C after all:

    extern char *my_strncpy(char *dest, const char *src, int n);

    char *my_strncpy(char * const dest, const char * const src, const int n) { /* ... */
    }

    This trick doesn't work in C++, which considers this as two distinct overloads.

    I was also wrong about Java - the 'final' keyword can be added to or removed from argument declarations freely, without affecting the method signature or Javadocs.

  204. Re:because - by tzanger · · Score: 1

    It'd be a wonderful language that does prevent all of these things without sacrificing the ability to do something because you do in fact know better than the compiler. I disagree with you about relying on compiler warnings. Use -Werror and get used to it. Use a lint utility and develop good coding habits. It's not impossible to write solid code in C, and it's not (much) harder to do than in other languages, either. With the exception of ambiguous statements which I agree with you on, -Werror takes care of a lot of the "duh" problems, and decent code reviews take care of stupid logic, which is a problem in any language.

  205. Re:because - by 19thNervousBreakdown · · Score: 1

    If you think correctly defining your function arguments' types is a pointless gotcha, you shouldn't call yourself either one, at least not in C. Maybe you think details like this are beneath you, and maybe you're right and this kind of thing should be abstracted away, but when you get right down to it, computers are just billions of on/off switches, and software has to be written at this level at some point to enable your high-level magic. If they don't get it right, your magic isn't possible. Did you think Python just sprang from the ether?

    --
    <xml><I><am><so><damn>Web 2.0</damn></so></am></I></xml>
  206. Re:because - by Joce640k · · Score: 1

    Hmm. I wonder why there's so much animosity towards C? It's a mystery.

    No it isn't. C is the language of ignorant, self-taught hackers*.

    C++ is a far, far better language but it requires sitting down and studying to use it properly. Hacking away at it won't do (well, ok, you may get there eventually but you could save a lot of time by sitting down for a few weeks and studying).

    (*) With one exception: There's platforms where C++ is a bad choice because of very restricted target platform or rotten C++ compiler on a particular platform. These platforms are getting very thin on the ground though so this is rarely a good excuse these days.

    And no, C isn't 'more efficient'. Not since the 1990's...

    --
    No sig today...
  207. Re:because - by Hognoxious · · Score: 1

    Why is that a good thing, or at least why is it worth it relative to the potential for errors and confusion?

    --
    Confucius say, "Find worm in apple - bad. Find half a worm - worse."
  208. Re:because - by antsbull · · Score: 1

    On the same note, you sound like the kind of programmer who has an ego - the worst kind you can deal with. The kind who will reimplement the wheel, because they think they can do better than a HashMap or a binary search, and cause massive budget overruns on projects. The kind who throws every design pattern possible at a problem so their code confuses others, and makes it extremely hard to maintain or change.

  209. Who hates it? by Anonymous Coward · · Score: 0

    Seriously ... I don't know a single programmer that "hates" C.

    Most of them, myself included, do not program in C, but that is not because we hate it ... it's because our jobs require us to use other languages!

  210. Its not the language it is how you use it by Anonymous Coward · · Score: 0

    I program in C when necessary. Over time I have built up a C library that is better than what is available in Python or Perl and is certainly a lot easier to deploy than anything in C++. One can write structured code (object-orientated if one must label it so) in C. The end result is usually more maintainable than anything written in C++, and it performs much much better. And, yes, I get paid lots of money because the result is always so reliable, trouble-free and absolutely fantastic.

    And to those who consider C to be unsafe - it is as safe as one wants to make it. Take strings, for example. Create a struct with pointer to the start of and to the end of string and allocated storage and you can have a perfectly safe string "class". The amazing thing is that so few people ever take simple remedial steps to make strings safe, unless same language designer provides it for them on a platter.

  211. Time for something new? by Anonymous Coward · · Score: 0

    There are obviously both good and bad features in C. Rather than arguing about whether C sucks or not, it would seem more useful to design a new and better language based on the lessons learned from decades of experience with C (and other languages). For example, one of the more annoying things about C is the difficulty in writing portable code, due to the numerous system dependencies. The language provides no way for the programmer to clearly indicate what he needs; he has to choose from a predefined set of data types that vary from one platform to another. Over time, this set of data types grows larger and more cumbersome as new types are added to address different needs. A better approach would be to let the user specify the range of values that he needs to represent, or the number of digits of precision that he requires, as is possible in Ada. The standard library could also stand redesign to reduce the risk of buffer overflows and to make the order of arguments more consistent (e.g. for fopen(), fgets(), fread(), etc.).

    C++ also has its share of design errors, one major flaw being that C++ often does things for you without being asked (which violates the zero overhead principle). Automatic initialization of class members makes it necessary to use the messy and confusing constructor initializer lists. It would be far better to signal an error if a constructor left a variable uninitialized or referenced a variable before it was initialized. Automatic code generation makes it necessary to create private constructors or use the goofy "= delete" notation when a constructor is not wanted. A better approach would be to have the programmer declare "default classname();" if he wanted a constructor to be generated automatically. Similarly for assignment methods, e.g. "default operator=();".

    Both languages would benefit from the ability to clearly specify the intended use of function arguments. If a pointer or reference argument is used in C or C++, perhaps the argument is intended to be modified by the function, or perhaps it is being passed that way simply because it is large. One can use "const" to control whether the argument can be modified, but the "const" notation is often confusing. In Ada, an argument is labeled "in" (input only), "out" (output only), or "in out" (both). This makes it easier to understand what is going on.

  212. Re:because - by Eraesr · · Score: 1

    I'm not saying Python is better for a business application than C. I'm just saying that for each problem, there is a tool. And there are situations where Python probably would offer some advantages over C and vice versa.

  213. Re:because - by Eraesr · · Score: 1

    You seem bitter.
    Maybe my statements were a bit bold and lacked the required subtlety, but you're making a completely incorrect assessment of me. I'm dealing with C often enough, but there are a lot of situations where using a language like C# or Java is the logical choice.
    Such languages won't always allow for greater productivity, sure, but in one case it does and in another it won't. You almost seem to have some sort of animosity towards C# or Java, throwing basically anyonethat is using or preferring these languages over C on a "newer programmer" pile who aren't worth the air they're breathing.

    Once again: all I'm trying to say is that in some situations you're better of using a language like Java or C# and in other situations you're better off using a language like C. Again other situations are better handled by PHP or ASP.NET. Choosing the right tool for the right job. That's all this is about. And anyone saying that the world is black and white where C is always better or where Java is always better is just not seeing things right.

  214. Re:because - by Anonymous Coward · · Score: 0

    But you basically just validated his point. C is a good tool for that job. That doesn't mean it's an ideal tool for everything else. Hell I'm mostly just a JavaScript guy but I'm comfy with using Python and I've tinkered with C and C++ because I recognize that there's value there. Anyway, the OP is being silly. It's the C dev's equivalent of "the attack on Christmas." I'm surprised he's not asking us to vote for somebody.

    After all, everybody hates Java, not C. Everybody who knows more languages than Java, at least. I'm surprised the Python devs at Google haven't erected barricades yet.

  215. Its not C I hate, but non-OOP by TheSkepticalOptimist · · Score: 1

    Object Oriented Programming is, by far, the more ideal way to develop modern software. Encapsulating data and responsibilities in a class is preferred over spreading responsibilities across many files.

    People who prefer C over C++ simply don't get OOP, period. They strain to identify the purpose of classes and encapsulation and thus assume it is not required. They are not "modern" developers, they are stuck in an era of procedural coding and have not crossed the threshold into viewing code as a collection of interactive components with specific responsibilities and structured data.

    Yes, C has its purpose if you are looking to build a quick and dirty library of procedures, but given that C++ is a super-set of C, there is no reason NOT to use C++ in favour of pure-C. The modern computer is highly multi-threaded and has more power and memory then the originators of C had ever envisioned. The added overhead of virtual tables and other class based mechanisms is not a significant reason NOT to use an OOP language. If I had a developer that toiled in pure-C and claimed that they were doing so for performance reasons, I would fire them on the spot.

    C is the basis of many languages and scripts, there is nothing wrong with the C Language, but the problem of a lack of OOP development I can't get over. I have never seen a C library that wasn't a sprawling mess of haphazzardly organized procedures and structs. There is little capacity to Unit test C, there is little capacity to apply pattern development in C, there is little opportunity to multi-thread C. C libraries become black boxes of untouchable code, prone to significant defects and non maintainable. C's limitations make it a dinosaur captured in tar and turned into a fossil.

    Anyone claiming that pure-C development is superior to OO development is not a good developer, period.

    --
    I haven't thought of anything clever to put here, but then again most of you haven't either.
  216. I love C by Anonymous Coward · · Score: 0

    Can be used to do just about anything and concise enough to be explained exhaustively in K&R's relatively short book.

    Sure it is low level, and potentially dangerous, but it lets you get under the hood in a way that more modern, higher level, languages do not.

  217. re Antiquated, clunky, and unsafe by Anonymous Coward · · Score: 0

    "Antiquated, clunky, and unsafe" - you don`t know what are you talking about

  218. Re:because - by Iniamyen · · Score: 1

    If I need to know the details, I'll Google it. I understand your point, especially when talking about a language as prevalent as C. However if you think anyone knows every language ever invented, you're mistaken. And given the stuff that's being taught as CS in colleges currently, expecting someone to know a language detail from a language they may never have worked with might end up filtering out some of the best engineering talent. My 2c.

  219. Re:because - by 19thNervousBreakdown · · Score: 1

    Of course somebody who isn't a C programmer shouldn't care about this. Both the previous poster and I were talking about C programmers, which is pretty clear from our posts.

    I can't decide if that detail escaped you, or if you're saying somebody hiring a C programmer should hire somebody that would need to google this kind of thing.

    --
    <xml><I><am><so><damn>Web 2.0</damn></so></am></I></xml>
  220. Motherbugger by asmcmnemonic · · Score: 1

    C was the first programming language I ever encountered in the era of programming. I still like it for its simplicity, speed, and compatibility with its counterpart, C++. I'm not saying that it's the best or worst programming language that everyone must learn or hate, but I just say that whatever keeps you happy in programming is the one for you, generally speaking.

  221. Re:because - by Anonymous Coward · · Score: 0

    There is no job approriate for PHP.

    It is also a fallacy that there is one best language for any given problem.

    If you think python is the best for a certain job, I can list at least 10 others that will be equally as good, perhaps better because maybe(likely) some other language has an abstraction that pythond does not that better models the problem at hand.

    Besides, your obvious lack of understanding of CS fundamentals and horrible lack of reading comprehension shows you to be an idiot.