Thread: Mixing C with C++ code

  1. #1
    Registered User
    Join Date
    Feb 2003
    Posts
    596

    Mixing C with C++ code

    I'm looking for some convincing arguments against mixing C with C++ code except where there is a "good" reason, i.e. to use C library functions that aren't available in C++.

    Frequently, these mixtures seem to turn up in students' programs involving i/o operations, probably most often because they didn't really know what they were doing & searched for code snippets containing any workable solution without regard to whether it's C or C++. Another reason might be that the students' introduction to programming was in C and they are being lazy about adopting C++ alternatives.

    I can argue that code that seems to be an indiscriminate mixture of C and C++
    - is irritating to read and
    - indicates sloppiness/carelessness on the part of the programmer
    but that sounds like it's just my personal prejudice.

    I can argue that "you are taking a course in C++, so you have to do things the C++ way," but that sounds very arbitrary and more or less begs the question.

    I have seen some remarks to the effect that "it's not a good idea to mix C and C++ io streams," but not much in terms of why.

    I'm sure that the experienced programmers here can be much more eloquent than I on this topic. Please give me your thoughts.

  2. #2
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Depends on what you want to achieve. There are certainly good arguments FOR mixing when you have a large portion of existing, working code that you need for your project - it's pretty pointless to translate it to C++ just because someone says so. If it needs rewriting for other reasons, sure, go ahead and C++'ise it.

    On the ohter hand, mixing I/O from C++ streams with stdio.h functions WILL requier calling the sync_with_stdio at either side of switching, so that any stream and stdio functions are in agreement on what's going on. If this is not done, I'd say it's grounds for loosing points on the completing of the project.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  3. #3
    Registered User
    Join Date
    Feb 2003
    Posts
    596
    Quote Originally Posted by matsp View Post
    Depends on what you want to achieve. There are certainly good arguments FOR mixing when you have a large portion of existing, working code that you need for your project - it's pretty pointless to translate it to C++ just because someone says so. If it needs rewriting for other reasons, sure, go ahead and C++'ise it.
    ...
    Mats
    Thanks Mats. That's fine, but it's not what I had in mind. I'm referring to completely new code that alternates between C and C++ for no apparent reason.

  4. #4
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Quote Originally Posted by R.Stiltskin View Post
    Thanks Mats. That's fine, but it's not what I had in mind. I'm referring to completely new code that alternates between C and C++ for no apparent reason.
    That's generally not a good thing, no - but there is no technical reason why this shouldn't generally work. One of the features of C++ is that it allows mixing C and C++ code as and when you wish - that's part the reason for it's popularity.

    As I said earlier mixing for example cout and printf or cin and scanf is definitely not a good idea, and it can lead to problems because the stdio FILE structure can hold data that is part of the input, and the C++ stream implementation won't be aware of what is happenning there.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  5. #5
    The larch
    Join Date
    May 2006
    Posts
    3,573
    On the ohter hand, mixing I/O from C++ streams with stdio.h functions WILL requier calling the sync_with_stdio at either side of switching, so that any stream and stdio functions are in agreement on what's going on.
    But (sync_with_stdio):

    By default, the standard iostream and cstdio streams are synchronized.
    For output, understanding format strings is a useful skill (and perhaps boost::format is too much to ask from students). You might point out the problems with the lack of type safety and that C input obviously doesn't support std::string and is therefore more open to all the C-string related issues. I can't think of a good reason why one shouldn't mix them in particular, though.
    I might be wrong.

    Thank you, anon. You sure know how to recognize different types of trees from quite a long way away.
    Quoted more than 1000 times (I hope).

  6. #6
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    The problem with the C++ standard library is that, unlike the C runtime, it isn't always available everywhere. This means you either have to distribute the C++ library along with your application, statically link it, or abstain from using it altogether.

    There is absolutely NOTHING deficient about the C library, it just isn't "object oriented." But for something like converting a string to an integer (atoi(), strtol()), do you really care?

    I find myself using strtol() and sscanf() a lot, even if I'm doing the actual input with an iostream.
    Code:
    //try
    //{
    	if (a) do { f( b); } while(1);
    	else   do { f(!b); } while(1);
    //}

  7. #7
    The larch
    Join Date
    May 2006
    Posts
    3,573
    If you are learning C++, C++ runtime is probably available.

    I have found myself using boost::lexical_cast a lot.

    The current project is using wxWidgets, though, so I'm using wxString::Format(const wxString&, ...) a lot.
    I might be wrong.

    Thank you, anon. You sure know how to recognize different types of trees from quite a long way away.
    Quoted more than 1000 times (I hope).

  8. #8
    Registered User
    Join Date
    Feb 2003
    Posts
    596
    I hope this thread won't degenerate into a "C++ is better"/"C is better" argument.

    I don't know, maybe it just boils down to a matter of style. Are you guys all saying that it doesn't matter and you don't mind if a subordinate or teammate hands you code that calls printf on one line, five lines later writes to cout, six lines after that is calling printf again, reads from a FILE * and writes to an ofstream?

  9. #9
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    Quote Originally Posted by R.Stiltskin View Post
    I don't know, maybe it just boils down to a matter of style. Are you guys all saying that it doesn't matter and you don't mind if a subordinate or teammate hands you code that calls printf on one line, five lines later writes to cout, six lines after that is calling printf again, reads from a FILE * and writes to an ofstream?
    If I saw that I'd probably puke. But if I saw exclusive use of C stdio instead of C++ streams, I'd probably be okay with it depending on the justification.
    Code:
    //try
    //{
    	if (a) do { f( b); } while(1);
    	else   do { f(!b); } while(1);
    //}

  10. #10
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    Quote Originally Posted by R.Stiltskin View Post
    Thanks Mats. That's fine, but it's not what I had in mind. I'm referring to completely new code that alternates between C and C++ for no apparent reason.
    As matsp said, there is actually no technical constraint preventing C and C++ interoperating (at least, if you're talking the 1989 C standard and C++). The C++ standard was specifically designed with backward compatibility in mind. The incompatibilities that exist are minor.

    The primary argument I see used is development time and maintainability. Code that unnecessarily mixes programing techniques, idioms, libraries etc tends to be harder to get right in the first place and, for code that changes over time, tends to require more effort to maintain. This is a real world argument as it directly affects software development costs, maintenance costs, and (in worst cases) willingness of employers to employ programmers. It is also the sort of argument novices routinely dismiss as irrelevant - if experienced programmers wish to encourage novice programmers to take heed, they need to use a club. [As an aside, I know one company that sacked a programmer who was given such guidance from his supervisor, and subsequent independant code reviews kept showing he was mixing up coding techniques].

    There is actually a technical constraint, thanks to the 1999 C standard, as that standard introduced incompatibilities with C++ and some of the techniques to work around those incompatibilities are compiler dependent. However, again, relatively few novices will write code that is directly affected by those incompatibilities and even fewer will use multiple compilers or care about portability and maintainability of code.

    Bottom line: if you're trying to convince novices who often think they know more than you do .... good luck!!!!
    Right 98% of the time, and don't care about the other 3%.

    If I seem grumpy or unhelpful in reply to you, or tell you you need to demonstrate more effort before you can expect help, it is likely you deserve it. Suck it up, Buttercup, and read this, this, and this before posting again.

  11. #11
    Registered User
    Join Date
    May 2007
    Posts
    147
    grumpy's got the goods here.

    Seasoned C++ developers will insist on a consistent coding convention and design convention. Mixing code standards creates less readable and less maintainable code, which in turn actually costs money.

    After years of C++ development, which follows from years of C development before '87 when C++ was first available to most of us, I can assure you that a comparison of the two paradigms makes it very clear that productivity is enhanced when using C++, as compared to C. The resulting work has more leverage, takes less time to develop, more work is encapsulated for future reuse (though many mid-level experienced developers tend NOT to understand this that well, and consider it a lesser point), the results tend to have fewer bugs, the resulting application can approach targets of greater ambition with smaller teams....

    The list gets long enough that at some point, those who know the merits of C++ development realize that mixing paradigms is a net loss.

    I completely agree with grumpy's experience - I've seen people dumped over this.

    Unfortunately, there are few concrete, simple explanations that adequately express the problem. It turns out that you have to reach a point of experience where you see it to get just how deep this runs. You've had some really good points along the way, and I realize that virtually all such debates conclude with the inexperienced we try to convince are simply not convinced, until they look back on their own development history and wonder why things worked out they way they did.

  12. #12
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    Quote Originally Posted by JVene View Post
    The list gets long enough that at some point, those who know the merits of C++ development realize that mixing paradigms is a net loss.
    The only thing I would add is that those who know the merits of C development realise the same thing.

    Both C and C++ techniques have their place - just rarely together, except in some code reuse situations.
    Right 98% of the time, and don't care about the other 3%.

    If I seem grumpy or unhelpful in reply to you, or tell you you need to demonstrate more effort before you can expect help, it is likely you deserve it. Suck it up, Buttercup, and read this, this, and this before posting again.

  13. #13
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by grumpy
    Code that unnecessarily mixes programing techniques, idioms, libraries etc tends to be harder to get right in the first place and, for code that changes over time, tends to require more effort to maintain.
    I agree, and I think that underlining "unnecessarily" is important. The key is to find an appropriate combination of programming paradigms to solve the problem, not to make use of language features just because you can, or to stick with just one paradigm because it is "good".

    Quote Originally Posted by JVene
    The list gets long enough that at some point, those who know the merits of C++ development realize that mixing paradigms is a net loss.
    I do not agree, but I suspect that you were merely being imprecise with your choice of words. I doubt that you would refuse to use the standard generic algorithms just because providing functions and function objects is effectively making use of a functional programming paradigm when the rest of your code is object oriented.
    Last edited by laserlight; 04-25-2009 at 12:50 AM.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  14. #14
    Registered User
    Join Date
    May 2007
    Posts
    147
    laserlight, you've touched upon one of the gray areas that makes the original question difficult to answer. In several of the books discussing modern C++ (the Exceptional C++ series, Stroustrup's works, Alexandrescu's works) I recall several points mentioned about the definition of an object which approach your point.

    If one defines an object as the collection of data and functions that act on that data relative to a particular subject (a loose one, it seems), then non-member functions can be part of an object.

    Stroustrup points out that it's an error to place some functions inside a class simply because they are conceptually part of that class. If a function is applicable more generically, such that it would serve it's purpose for other objects or other contexts, placing it inside a class may limit it's usefulness (or re-usefulness).

    I forget which in this series points this out, but indeed, as you've clarified here, an algorithm may be so simply a process and not a candidate for an object that it's implementation is purely a function. Many of the STL algorithms fall into this category. One of the aspects about the STL that surprised most of us when it was first released was the appearance, at first glance, that it wasn't as 'object oriented' as we had come to expect from pre-template coding paradigms.

    This is where it gets gray and fuzzy. As I read the message is several of these texts I mentioned, the message is that "object oriented" isn't a function of the language constructs, but of the method of thought in design. This is partly what brings forward a school of thought that OOP and OOD can be implemented in C (and sometimes rather heated arguments result).

    This also tells me that the original question is difficult to answer, because there is fine grained detail that leaves the subject of C++, or of C++ vs C, and impels me to rephrase the question, which seems a little rude (mixing OOP and completely non-OOP techniques).

    As you're point addresses, the implementation of a purely algorithmic subject, say Qsort, isn't going to be made better or much different through an effort to impose OOD or unique C++ constructs into it. It is one reason 'sort' is an algorithm in STL, without much hint of OOP in it, except for the predicate.

    The imposition of a different way to provide the expression of the comparison seems minor, perhaps trivial. The C library's qsort function takes a pointer to a function, and is a staple of the C library. STL's sort might seem superlative, perhaps only a wrapper to hide the intricacy of supplying a suitable set of parameters for C's qsort, but it's a bit more than that I'm sure you know.

    The fact that STL's sort accepts a predicate that is not simply a pointer to a function means the comparison can be optimized by the compiler to an inline. The reason it's possible is because information is not obstructed between the call made to the comparison and the code that describes that comparison. In C's qsort, the pointer to a function stops the compiler's ability to 'understand' the comparison, it is simply relegated to making a call to the correct function. The STL's sort algorithm may be faster as a result.

    This notion of the ability to express even algorithmic parameters in a way that provides more information to the compiler with little effort added to the programmer's burdens is an important property of OOP and OOD thinking.

    You are most correct at pointing out it's more complicated than some simple phrase; algorithms are what they are, and at the most elementary statements everything appears to be just a list of instructions. What makes an object, and what constitutes the OOP paradigm, or as the OP inquired C++ vs C coding, must follow the context of the thought being expressed as code.

  15. #15
    Registered User
    Join Date
    Feb 2003
    Posts
    596
    JVene, thanks for your very interesting and insightful comments. However, when I posed the original question, I was trying to provoke a discussion that would be instructive to beginning programmers and hopefully appropriate for inclusion as an FAQ item.

    Your point, and laserlight's, begin to go well beyond the level which I intended. I certainly learned something from it, but I'm afraid it will tend to steer discussion away from the original question. Perhaps the moderator would consider splitting off a separate thread titled something along the lines of "Object-Oriented versus Procedural Design".

    On the other hand, maybe matsp, brewbuck and grumpy have already said all that needs to be said about the original question...

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Enforcing Machine Code Restrictions?
    By SMurf in forum Tech Board
    Replies: 21
    Last Post: 03-30-2009, 07:34 AM
  2. mixing code with declarations
    By robwhit in forum C Programming
    Replies: 12
    Last Post: 01-31-2008, 12:55 AM
  3. Obfuscated Code Contest: The Results
    By Stack Overflow in forum Contests Board
    Replies: 29
    Last Post: 02-18-2005, 05:39 PM
  4. Obfuscated Code Contest
    By Stack Overflow in forum Contests Board
    Replies: 51
    Last Post: 01-21-2005, 04:17 PM
  5. Interface Question
    By smog890 in forum C Programming
    Replies: 11
    Last Post: 06-03-2002, 05:06 PM