tags:

views:

1105

answers:

10

Well that may sound like a troll question, but since C++ seems hard to fully master (and I never really knew STL was actually "part" of it), I wanted to know what are the disadvantages to use C instead of C++ when not relying much on OOP.

C++ can have a very much sophisticated syntax sometimes, which is kinda confusing me while trying to use OGRE3D for example...

+5  A: 

References are done automatically and much safer compared to pointers, the standard library is far more extensive, templates make code extremely customizable and substantially faster and safer. C++ offers fantastic code use/reuse and organization. Also, if you don't rely much on OOP, then you're doing it wrong. There's times when objects are not appropriate, but they're not the majority of scenarios.

DeadMG
References are const pointers + syntactic sugar. There's no advantage in safety whatsoever, and they eliminate the visual cue that a variable is passed by reference.
Ben Voigt
DeadMG
@Dead: Hm? What about `int array[10];` and `int (`?
FredOverflow
The problem with references is that they are less functional than pointers, so still you have to use pointers *a lot*.
el.pescado
@FredOverflow: You could do that- but you'd have to be silly to use an array anyway. There's vectors for heap and a boost::array for wrapping stack arrays. So why would you ever use such an array? @el.pescado: Pointers still have their uses, for sure. But references are their most common use case, and a superior solution where they can be used.
DeadMG
@el.pescado: References were introduced to support call by reference, and nothing else. They were *never* in any way meant to replace pointers.
FredOverflow
@DeadMG: You say that "When you have an int int
Ben Voigt
-1 for "doing it wrong" and mythical "reference safety".
SigTerm
It annoys me that when I pass an object to a function, that I cannot be sure whether or not that function will modify the object without looking up the function declaration.
dreamlax
+51  A: 

Non-OO features that C++ has that C does not:

  1. Templates
  2. Function overloading
  3. References
  4. Namespaces
  5. You can use structs and enums without writing struct or enum before every declaration or using typedefs.
  6. Even if you don't define your own classes, using C++'s string and container classes is still often more convenient and safe to work with than c-style strings and arrays.
  7. Type safety (even though some would call it weak)
  8. Exceptions
  9. Variable declarations in conditionals, C99 only has it in for
sepp2k
8. variable declarations in conditionals, C99 only has it in `for`
Jens Gustedt
@Jens: I just learned something new.
Cam
Type safety is probably the first and most significant advantage to an experienced C programmer.
Ben Voigt
You forgot the most important C++ feature: you don't have to write "return 0;" at the end of main!
Amnon
@Amnon: I think you can leave out `return 0;` in C99 as well.
FredOverflow
Good, but you should have mentioned standard template library as well.
SigTerm
10. inane, long-windend errors by compiler implementations. (that's a feature, right? :) )
BobbyShaftoe
@BobbyShaftoe: I'd say that's a subfeature of 1.
sepp2k
+1  A: 

Other than the upsides that sepp2k noted (and I aggree with) it certainly also has some little downsides that have not directly to do with OO. Come to mind the lack of __VA_ARGS__ for the preprocessor and the context sensitivity. Consider something like:

switch (argc) {
 case 1: /* empty statement */;
         toto T;
 case 2: break;
}

In C, whenever the compiler encounters such a piece of code, and argc and toto are known, this is valid. (Sure we might get a warning for the unitialized T afterwards, whence we use it.)

In C++ this depends on the type toto. If it is a POD, everything is fine (well, as fine as for C). If it has a constructor the code is not valid: jump to case label crosses initialization of 'toto T'.

So in some sense, for C++ you must understand the underlying types to see if a control flow is valid.

Jens Gustedt
Note that `__VA_ARGS__` was added to C in the C99 standard, after the current C++ standard was published. C++0x adds support for the C99 preprocessing features.
James McNellis
It is illegal in C (even in C99) to declare a variable directly after a label, because a declaration is not a statement and labels must only be part of a statement.
dreamlax
@dreamlax: thanks, I corrected the syntax
Jens Gustedt
+3  A: 

[Note: this is a subjective response but the question itself tends to invoke subjective responses by nature].

C++ is a multi-paradigm language and there's a lot more to it than OOP. However, to suggest it's simply better than C is a bit... bold. :-D In the hands of an experienced C coder, and for the right purposes, C code can be very elegant and simple. Consider the Lua interpreter which is coded in C; it compiles to a very small binary which would have likely been a lot bigger even in the hands of an equally skilled C++ programmer, and is therefore well-suited for embedded use. C generally won't be as safe (ex: implicit casting, requires manual resource cleanup, etc) which is one thing which C++ strives to do a little better than C, but it also won't burden the programmer with awkward casting syntax (in C++ one shouldn't need to cast often, but in C it's quite common), e.g.

On the other hand, and I'm trying to speak very generally, C++ can actually make it easier to write more efficient code, particularly for code that needs to work across multiple types. The qsort vs std::sort benchmarks are a classic example of this and how C++, through templates and inlined function objects, can provide cost-free abstractions. In C one would have to write a separate sorting algorithm for every type by hand or stuff it in a macro to achieve comparable results.

Most C++ programmers who migrated from C never look back. I might be an oddball, but I still find C to be useful for implementing small scale libraries. For a start, it's a bit easier to port and builds super fast. For these kinds of things, I take implicit casting for granted. I would hate to work with any C code on a large scale, however, and have unfortunately have to do this from time to time.

As for specific differences, sepp2k already pointed out a pretty comprehensive list.

C++ is simply better than C, because C doesn't offer anything that C++ doesn't, but C++ offers a lot than C++ doesn't.
DeadMG
@DeadMG: It is simply not true that C doesn't offer anything that C++ doesn't: long long int data type, variadic macros, compound literals, variable-length arrays, native complex-number types, and the restrict keyword.
Dipstick
Faster (albeit still not fast) compilers.
el.pescado
And, i'd note that saying "X has all features of Y and some more, so X is better" is just plain wrong. Imagine a programming language that has all features of all other programming languages. Would it be the best programming language in the world? I doubt it.
el.pescado
@DeadMG also offering less is sometimes better. Consider Python's rules on formatting: when it comes to what's allowed, there's a lot less than C/C++/Java/C#/etc. I don't like it, but the restriction results in greater code uniformity. Implicit pointer conversion, for example, while being very dangerous and can easily lead to portability problems, is quite useful in C. Unfortunately there seem to be a lot more bad C++ programmers than good ones. It's easier to find a good C programmer than a bad C++ programmer. I'd take a C programmer who writes simple code to a C++ programmer who misuses[...]
[...] inheritance as a way to merely add functionality to base classes any day (the common misuse of inheritance is one of the main things that makes me grimace about how average coders use C++). Now if everyone I worked with could write exceptional, modern C++ code, I'd easily choose C++, but there are still way too many people using C++ like C with OOP and don't even understand good object-oriented design (large hierarchies are generally a bad thing regardless of that fact that these are predominantly used in Java, .NET, and even QT).
s/bad C++ programmer/good C++ programmer/. Note that I'm still a C++ enthusiast by far, it is my passion, but I've found too many professionals who can't even understand the generic qualities of the standard-library iterators, e.g. Unfortunately professionals usually don't take the time to stay up to date with the languages they use, and in my field at least, I've found that getting too happy with modern C++ can leave too many of my co-workers behind. :-(
@stinky472: A bad C programmer won't produce better code than an equivalently bad C++ programmer, he'll produce worse. Yes, the features in C++ are easily abusable. But, they're better and safer than C's common idioms. Python's rules on formatting are goddamn terrible. Yes, I normally indent my code, but I indent it how I like, not how you say. When you develop C++, if you can't get it right, that's your problem, not the fault of the language, and C++ is incredibly supporting compared to C in writing good code.
DeadMG
@DeadMG regardless, there are still too many C++ programmers who can't get it right. I agree with you; people should learn the language. But when you work in a team, you often have to dumb your code down to the lowest common denominator, and among C++ "professionals", there are too many weak links. At least this has been the case in my field (raytracing). They're writing C++ code like it's the 80s: most don't even understand what RAII is let alone something as sophisticated as generic algorithms, lambda functions, etc. let alone how to write a decent class hierarchy.
For such programmers, I trust them more when they use C in their own separate module with an interface we can use rather than let them try to write C++ code.
@DeadMG another thing worth looking at is dealing with modules at runtime. Unfortunately most C++ programmers I work with don't understand the subleties of when memory allocations and deallocations occur. For instance, it is incorrect to pass std::vector by reference across modules as that would be prone to modifications, and therefore memory allocations/deallocations across modules. We also can't throw exceptions across modules, etc. I know enough to avoid these cases, but I've found it impossible to explain to my co-workers and meet our deadlines, so we just use C for our API headers.
[...] and sometimes just C for the implementations. I've spent over 15 years studying, learning, and practicing modern C++ techniques and there are still new things I'm learning. It takes a lot longer to master the C++ language and its multi-paradigm nature than C. The language can be learned more quickly, but learning how to use it effectively can take over a decade of practice and study, and I don't think any single language has had more paradigm shifts than C++. Consider over a decade ago when Loki was considered really good only for most of it to become obsolete with boost.
@stinky472: If they can't grasp the concepts of their host language, then why would they do any better in another?
DeadMG
@DeadMG They were traditionally C programmers. The host language isn't necessarily C++ either - we use a mix of both (though we never mix the two in a single project/module) and it originated as C code. Consider the Microsoft programmers - compare the Win32 API in C to MFc. I'd take the C results anytime. To be good at C++, one really needs to have the passion and interest in the language to use it well. As Stroustrup said, "In C++ it's harder to shoot yourself in the foot, but when you do, you blow off your whole leg."
@Stinky472: Ah, right. So, rather than C++ being the problem, the problem is that you got a bunch of C programmers and asked them to use an unfamiliar language. Would you expect great results if you asked them to code in Lua, Java, C#, PHP?
DeadMG
@DeadMG I'd expect them to be able to learn those faster. You ever work with a bad, over-ambitious C++ programmer? Ex: someone who thinks Java is a shining example of solid object-oriented programming and thinks C++ is mainly C with objects and creates fragile object hiearchies which are constantly prone to rewrites which sometimes gets so out of hand that the entire hierarchy has to be deprecated. For such coders, I'd trust them with C more than C++, since if they write crappy code, at least it tends to be unambitious.
In other words, when a bad C programmer dealing with procedural programming messes up, I find memory leaks, segfaults, poor and often ignored error-handling, and things of that sort: a bunch of localized implementation problems. When a bad C++ programmer messes up, I find design-level problems which can affect the entire system. The only thing worse is a C programmer trying to write C++-like code, in which case one can find the most disastrous kinds of design-level problems.
The sad reality is that a lot of C++ programmers aren't really that good. Consider how Google's Style Guide generally encourages C++ classes to have disabled copy constructors and assignment. I'd hate working under such standards, but at the same time look at how many C++ 'professionals' don't see anything wrong with void f(std::string str) when 'f' only needs 'str' for read-only purposes. I can actually believe such terrible C++ programmers to write more efficient code in languages like Java or C# just because of how inefficient poorly written C++ code can get with unnecessary copies.
@stinky472: The only reason that a bad C++ programmer has system-endemic problems is because C++ allows you to actually design systems in it in a reasonable timeframe. C, on the other hand, if they actually wrote code that did the same thing, would be just as bad. The reason that poor C code leads to poor implementation is because implementing C code takes years compared to C++. Besides, why are your new C++ programmers doing system design?
DeadMG
@DeadMG C++ allows freedom: the freedom to create the worst kinds of designs imaginable in addition to the best kinds. It is easy enough to teach a C programmer simple guidelines like prefer defining structs in a cpp file instead of a header (avoiding data coupling) and provide functions to act on opaque pointers. That won't yield great designs (semi-OOP procedural interfaces at best), but is unlikely to yield hopelessly bad ones either. Now take the same average programmer and give him the ability to define class hierarchies, and he'll make a disaster of the situation.
@DeadMG these aren't new C++ programmers. They've been using C++ longer than I have: about 30 years. The senior engineers tend to be the most hopeless ones; the ones that came from old school C++ and have been permanently brain-damaged by C. They're also not doing much system design; that's mainly what I do, but they still have to create public interfaces for the functionality that they provide.
To make hopelessly bad interfaces that require complete rewrites of the entire system usually requires a very *inventive* yet inexperienced programmer. The thing with C programmers is that they're usually not quite as inventive as C++ programmers, so the ones that aren't good usually avoid disastrous designs even if their designs are typically bad (bad is much better than hopelessly bad).
To provide a little context, historically we had a system engineer who designed interfaces with C emulating C++ (trying to emulate vtables and inheritance through C). That was the most disastrous design. Later we got a C++ programmer who was mainly a Java enthusiast who rewrote the system using deep object hierarchies. That was better but still quite awful (the hierarchies were fragile and tightly coupled). Finally I came in and eventually got this position. My philosophy is based on Modern C++: avoid deep hierarchies when possible, avoid inheritance when composition is possible, prefer free..
... functions to adding methods to an already complete class interface (avoid monolithism), use RAII for *everything*, etc. Nevertheless, I find it hard not to leave a lot of the seniors behind, so we compromise and allow C and write some local implementations in C. Then I wrap that stuff into a C++, RAII-conforming class. With some programmers, it's easier to trust them with languages other than C++.
+15  A: 

I'm a big fan of C who over time has become a big fan of C++. One of the big reasons for that is the STL ( the Standard Template Library ) and Boost.

Between the two of them it makes it very easy to write powerful portable applications.

Robert S. Barnes
Note that both STL and Boost rely on the OOP attribute of the C++ language.
rursw1
+10  A: 

One "feature" that hasn't been mentioned much (but I think is noteworthy) is that the C++ compiler community seems to be willing to go to a lot more work to produce conforming implementations. Back when the standard that eventually became C89/90 was in work, nearly every compiler vendor worked at conforming with the latest drafts of the standard, and (especially when the standard was close to complete) really put a lot of work into conforming as closely as they could.

That's no longer the case. The C99 standard was (obviously enough) completed over a decade ago, but there's still basically only one implementation that makes a serious attempt at conforming with the whole standard (Comeau). A few others (e.g., gcc) have added some C99 features, but are still missing a fair number of others. One (pcc) is in the rather paradoxical position of having added nearly all of the features specific to C99, but doesn't come very close to meeting the requirements of C89/90.

Given the complexity of C++, producing a conforming implementation is a much more difficult task. Despite this, I'd guess there are already more implementations that are at least really close to conforming with C++ 0x (due to be ratified a year or two from now) than with C99 (ratified roughly a decade ago). Just to pick an arbitrary number, I'd expect to see 3 conforming1 implementations of C++0x sooner than 3 conforming implementations of C99 (in fact, I'd almost expect that many the day it's ratified).

  1. Of course, "conforming" in this case means "to a practical degree" -- I'm pretty sure every implementation of C and C++ has at least a few defects that prevents perfect conformance. The same is true for most other languages, the only obvious exceptions being languages that are defined in terms of a particular implementation.
Jerry Coffin
That's an interesting point. And I agree, it is a pretty noteworthy difference. +1
jalf
+1, but: besides Edison Design Group and the gcc team, are there really that much "original" (not "flavour") C++ compliler vendors? The abovementioned strength of C++ may actually appear much "weaker", I mean.
mlvljr
@mlvljr: Microsoft develops its own frontend for Visual C++. I agree with Jerry's point, especially since some major vendors (like Microsoft) have abandoned C standards conformance altogether.
James McNellis
This may be true but I think we can live without C99. I think it's more interesting to restrict the discussion to ANSI C90.
BobbyShaftoe
@Bobby: If you restrict C to C89, then I'd say the single biggest factor is much better I18N support. In C, it's a pain just to print out a number formatted as "1,234.56" or "1.234,56" (depending on locale) instead of "1234.56" (and formatting something like currency correctly is harder still). C++ makes these trivial.
Jerry Coffin
+1  A: 

You can continue to write essentially C code but compile it as C++ and get the benefit of stronger type checking, and therefore more robust code.

You can then if you wish introduce the useful elements of C++ that have nothing to do with OO, such as a built-in bool, function overloading, and better defined const handling (no need to use macros for literal constant symbols).

It is not even too much of a stretch to using some of the easier to understand and use elements of the standard library such as std::string and iostreams, and even std::vector as a "better array"; you do not have to learn much C++ or understand OOP to take advantage of these improved interfaces.

Between OOP an procedural programming there is an intermediate Object Based Programming, which C++ supports and which is simpler to understand and learn and almost as useful as full OOP. Basically it uses abstract data types rather than full classes and eschews inheritance and polymorphism. To be honest it is what many C++ programmers write in any case.

Clifford
If you write C code and feed it through a C++ compiler, how does that give you stronger type checking To benefit from stronger type checking, you have to write more type safe code, which means it is no longer "essentially C".
jalf
@jalf: The C++ compiler will perform stronger type checking. Type safe code will compile in both C and C++, but the C compiler doesn't give you as much feedback about things like type-punning.
Ben Voigt
+6  A: 

Why C++ is better than C? Besides the obvious list of features, in my opinion the real answer is that there's no good reason to still use C instead of C++. Even if you don't use OOP, you can use it as a better C. Even if you use just once a unique feature of C++ in your program, C++ is already a winner.

On the other hand, there's no disadvantage in using C++: it retains the performance goals of C and it is a quite low level language, while allowing very powerful things. And you will not miss any C feature using C++!

And don't forget the wide user base and the rich libraries and frameworks available.

By the way, C99 has added some interesting features but after a decade there's still very limited compiler support (so you are bound to ANSI C). In the meantime C++ evolved as well and the compiler vendors are committed to providing conforming implementations.

Lorenzo
One good reason would be **much** faster compilers. The second, there're devices that still don't support C++.
Pavel Radzivilovsky
Faster compilers? In the last 15 years research and development in C/C++ compilers is almost entirely driven by C++. Performance gains in C compilers are a direct consequence of C++ compiler improvements. And almost any embedded device can be programmed with C++ (with the exception of very simple PICs where you anyway would use assembly instead of C...)
Lorenzo
Reasons to use C: Because it has a clear readable spec, understandable by nearly anyone with a small amount of patience. Because it has a formally specified syntax. Because name mangling is obnoxious in some circumstances, even if you can work around it. Because C99 has a whole bunch of nice features that still aren't in C++. Because I frequently deal with platforms that don't have C++ support.
Stephen Canon
Ok: inane compiler errors, name mangling, code size, no possibility of operator overloading (sometimes people write software in groups larger than 1), etc, etc. Sure, I think C++ is a great language and has its place but to say there is no reason to use ANSI C because of C++ is a bit ridiculous.
BobbyShaftoe
The only true reason is a platform without C++ support (personally, as an embedded developer, I found that only once). All other reason are pointless and typical from people that don't really understand C++.
Lorenzo
`ANSI C` doesn't mean anything, both C89-90 and C99 have been standardized by both ANSI and ISO.
Andreas Bonini
Lorenzo
+1  A: 

One reason to write libraries in C is that it is very easy to use that library across languages since the C ABI is very simple, compared to the name-mangling mess that is C++ ABI. Creating C interfaces to the C++ libs might be a decent solution, but if you can express your API easily with C syntax, why write it in C++ to begin with?

Many C99 features are very nice, and are still not in C++.

Maister