• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 338
  • Last Modified:

C functions in C++ code

Is there any harm in using old-school C code inside of a C++ application?

If so, please explain the harm in using fread() in C++ as opposed to the fstream and printf() as opposed to cout.

Is there an issue of memory handling?
   If so, should there be any concern in linking
   your C++ app to routines originally written in C?

Is there an issue of style?

  • 4
  • 3
  • 2
  • +2
1 Solution
nietod is currently answering a lot of this


and I don't feel like stealing his words, having just read them.  

When it comes to linking to C routines, there is no problem, as long as they were written well, the new-school simply makes it easier to write good programs today.  The motivation behind keeping C++ similar to C was largely so that old code would still be valid.
> and I don't feel like stealing his words, having just read them.  

erm, I meant that I didn't want to plagiarise; not that the words weren't good enough :)
Concerto Cloud for Software Providers & ISVs

Can Concerto Cloud Services help you focus on evolving your application offerings, while delivering the best cloud experience to your customers? From DevOps to revenue models and customer support, the answer is yes!

Learn how Concerto can help you.

TriskelionAuthor Commented:
Understood, however, that reference pertains to strings and string classes.  I posted this question because of a statement 'nietod' made to a comment I posted in:

nietod >
   Fisr of all, you shouldn't use fread() in C++,
   it should be an fstream. <

I didn't want to branch the 'wmike' question on binary files to a discussion on language and specifically the use of C inside C++.

Plus, it's been a while since I asked any questions here.
>>nietod >
>>  Fisr of all, you shouldn't use fread() in C++,
>>  it should be an fstream. <

Well, I *personally* think  that - except from the question of style - there's no reason NOT to use the CRT functions in a C++ program, as even the STL itself uses them, e.g.


        // TEMPLATE FUNCTION _Fgetc
template<class _E> inline
    bool _Fgetc(_E& _C, _Filet *_Fi)
    {return (fread(&_C, sizeof (_E), 1, _Fi) == 1); }

>> f so, please explain the harm in
>> using fread() in C++ as opposed
>> to the fstream and printf() as opposed
>> to cout.
the C I/O routnines are non-type safe.  This means that you can make seriious mistakes with them and the compiler is unable to catch them.  They are also not extensible to new data types.   i.e. Try to use scanf() to read a class Widget object, you can't.  They are also not internationalized.  You can't make them ouput usign a "," for a decimal point like is required in some langauges.  etc.

The C++ I/O routines solve all these problems.  The lack of type safety in the VA procedures was a know problem and Bjarne Stoustrup developed the first stream class as a solution to this very problem.  the current sream clases bear almost no similarith to what he developed, except that they do solve that problem and all the others I mentioned.

however if you are talking about mixed lanauge programming, that is a totally different issue.  

C++ was designed to be able to be used in a mixed language program with C.  But you must follow certain rules.  First of all, you must make the entry point procedure (that is main()) a C++ procedure.  (some compilers might allow you to get around this restriction, but the standard itself does not, it allows compilers to have the restriction if they want it, and most will.)  Second you need to use extern "c" to control name decoration as needed.

when C++ creates a function it usually "decorates" the name with a code that expresses the functon's parameters.  This decorated name is what appears in the object code and what the linker sees.  This decorated names is used to help fucntion overloading work.  It is used internally by the linker and by the compiler to insure that no two functions, actually have the same name, even overloaded functions.

The problem with this is that Most lanauges don't support name decoration--and if they did, they would not necessarily do it the same way as the C++ compiler you use.  C in particualr does not support name decoration.  So when  you try to link C++ code with C (or other langauges) you will get linker errors because C++ produces decorated anmes and looks for decorated names, but C produces non-decorated and looks for non-decorated names.

The solution to this is to use exterm "C" on the C++ side.  When a function written in C++ is defines as extern "C", like

extern "c" int increment(int i)
   return i + 1;

the function is given a non-decorated name.  This meands the function can be called from another langauge.   (It also means that you can't have another overload of the function, at least not another overload that is also extern "c".)

if you use extern "c" when you import a function into C++ using its declaration like

extern "c" int increment(int i);

C++ will look for the function with its undecoarated name. This allows a C function to be called from C++.
I missed this

>> Fisr of all, you shouldn't use fread() in C++,
>> it should be an fstream.
That is because fread has known problems that fstream solves.  

fread is not type safe, leading to possible errors.  

The FILE * operations are not exception safe and can leave files opened under an exception

The FILE * operatiosn are not extensible to class types.

The FILE * operations are not internationalized.

The FILE *operations are not I/O safe, you can open a file for readin and then try to write to it.  (You can do that with C++ streams too, but there are goods safegaurds to prevent it, if you choose to use them.)

all these problems are fixed with C++ I/O stream objects.  It seems absurd to use C I/O instead.   This is especially true if the reason is that "C++ I/O does not support binary operations on files".  It supports it just as well as it supports ASCII I/O and both types of support exceed the C I/O support.
TriskelionAuthor Commented:
Ok (great comments by the way...) do you consider the CStdioFile class a safe way to use "FILE *" in a C++ app?

It seems to be only a wrapper of the old functions.
First of all CStdioFile is MFC specific, so it is not portable.  But if you are only on windows, that might not be a concern.

As far as I know, CStdioFile solves most of the problems that are associated with C streams.  It is typesafe, it is exception safe.  (as far as I know).  However it is not as general purpose as the STL stream objects.  it is not (probably) as extensible and does not support internationalization etc.  These are much smaller flaws however, they may not matter as much to you.  Bugs always matter, these are more fancy frills, not bug prevention, and might be less important.  The fact that it deals with CString's is very convenient when you are working with MFC.

If you are not using MFC, it certainly doesn't make sense to switch to useing MFC just for this class.  The STL classes are at least as powerful.  if you are already using MFC, whethor you should use this or the C++ streams is going to depend on lots of factors.
TriskelionAuthor Commented:
The answer I was seeking was in the 4 comments by nietod.

Featured Post


Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

  • 4
  • 3
  • 2
  • +2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now