|
-
January 24th, 2003, 08:56 AM
#1
Can C++ programs use C libraries?
I have a C program which is required to call functions in a C library which I do not have the source codes. However, the library crashes my program due to some unknown exceptions, probably due to pointers errors, but they occur very rarely.
I was thinking of converting my C program to C++. This way, it will be possible to make use of the exception handling mechanisms of C++, such that my program will not crash when errors occur in the library again.
Can C++ programs use C libraries in the first place? How else can I prevent errors in the library from crashing my program???
-
January 24th, 2003, 09:46 AM
#2
Yes, C++ programs can use C libraries. You just have to use
extern "C" so that name mangling will be suppressed. Since you
are getting a crash, you're obviously linking so you know this.
One possible source of errors is that some C function is creating
memory with malloc() and you're getting rid of that memory with
delete. Mixing malloc() and free() with new and delete is a fairly
common source of errors when mixing C and C++.
--Paul
-
January 24th, 2003, 09:53 AM
#3
I never had a problem with using malloc(), free(), new and delete all in the same program. Just have to remember that when you call malloc() you must use free(), and when you use new you must use delete. So, your C++ code must use free() to release any memory allocated in the C library (unless it was allocated by some other unusual way such as LocalAlloc(). Most 3d party libraries I've seen have that well documented.
-
January 24th, 2003, 10:11 AM
#4
scorpion,
can you be more specific?
what compiler, OS, library?
what are the symptoms of the crash?
regards,
-ron
-
January 24th, 2003, 11:19 AM
#5
I have a C program which is required to call functions in a C library which I do not have the source codes. However, the library crashes my program due to some unknown exceptions, probably due to pointers errors, but they occur very rarely.
I was thinking of converting my C program to C++. This way, it will be possible to make use of the exception handling mechanisms of C++, such that my program will not crash when errors occur in the library again.
Can C++ programs use C libraries in the first place? How else can I prevent errors in the library from crashing my program???
It is NOT necessary to use C++ exception mechanism to catch an exception thrown from some C library. Because there is no way a C library can throw a C++ exception. Even if it wants, it hasn't learned how to throw C++ exception yet!!! The exception is either triggered by some C code, and there is C ways to handle it. The exception may be trigered by the OS, and then there is OS ways to handle it. The C code could even be triggered by the CPU hardware, and there is CPU hardware way of handling them.
For topics of how C code can trigger and catch exceptions, search for stuff like "longjmp", "setjmp". Actually all C++ exception stuff boils down to the C long jump etc underneath.
C++ exceptions are fundamentally BAD thing in programming. Avoid using them at all cost. Prior to C++, in the long history of C programming, people rarely used longjmp(), setjmp etc.. even though it is defined. There are good reasons to it. Once C++ exception is invented, people begin to abuse C++ exceptions, which boils down to use the setjmp and longjmp that historically never been used. That is BAD.
In the OP's specific problem. What you need to do is not trying to catch the crash in the C library. If it is the fault of you pass the wrong parameters, then correct your own code. If it is the fault of the library itself doing something wrong, then debug the library. If it is a third party library that happen to be crappy. Then there is nothing you can do other than telling them that and turn around and by another product from a fourth party vendor.
-
January 24th, 2003, 11:45 AM
#6
I think Anthony may be correct about C not being able to create exceptions and about how you should research your problem.
If it is a problem with the third party library, then you should check with the people who made the library. They may have a newer version that fixes the bug you are seeing or if they have never seen the bug, they may work with you to solve the problem and then provide you a fixed library. If this doesn't work out, then you may want to investigate other libraries or (gulp...) some workaround of your own if you *must* use their library.
- Kevin
-
January 24th, 2003, 12:07 PM
#7
> C++ exceptions are fundamentally BAD thing in
> programming. Avoid using them at all cost.
You're free to hold whatever views you want as usual but others should take note. Nothing is perfect and exceptions are no exception (bad pun not intended). Anthony's views are nevertheless considered extreme by most developers. To simply call them BAD and advocate against their use "at all costs" flies in the face of what most would consider balanced judgment. And as I recall from one long discussion on the matter a year or two ago, you didn't seem to be aware of exception specifications so the point you were arguing was ill-formed (and wrong). I don't say this to start a fight on the subject (I won't respond) but all newcomers should do their own research first (and consider why exceptions - a feature that has solid advantages over return codes and which most developers appreciate - made it to standard in the first place).
-
January 24th, 2003, 12:45 PM
#8
I also have to agree with Sef here (and I'm not looking to participate in a fight either).
-
January 24th, 2003, 12:58 PM
#9
I used to think SetJmp() and LongJmp() were soooo cool when I was writing C code that I used it quite often to return from very deeply nested function calls. Relieved me from writing a lot of complex function return code checks. I missed it alot when I started writing C++ code but eventually found better ways of doing that. Now, I don't write C code anymore, but rarely use exceptions (try/catch blocks) unless I KNOW that some 3d party or M$ Win32 API function could cause one.
Anthony is correct though -- they should never be used to cover-up a program bug.
-
January 25th, 2003, 01:20 AM
#10
exceptions
Originally posted by scorpicorn
I have a C program which is required to call functions in a C library which I do not have the source codes. However, the library crashes my program due to some unknown exceptions, probably due to pointers errors, but they occur very rarely.
I was thinking of converting my C program to C++. This way, it will be possible to make use of the exception handling mechanisms of C++, such that my program will not crash when errors occur in the library again.
When this occurs, it is often time to move away from a legacy library and look for alternative acquisitions. But I understand that it is often not possible to do this immediately, because companies (particularly small ones) have to count their costs. So you may need to patch it up for meantime...
Unfortunately, the best solution will have an OS dependency. You have to rely on any OS method of failure notification available (signals, interrupts, exceptions (like Windows, not c++), etc.), and program their proper operation through the OS API. You could even throw on a hierarchy abstraction manager (like an Abstract Factory) if you needed to still work in different OSes, to make it easier and quicker to compile updates. This probably wouldn't require you going out of c if there were no other reasons for you to switch to c++.
Originally posted by AnthonyMai
C++ exceptions are fundamentally BAD thing in programming. Avoid using them at all cost. Prior to C++, in the long history of C programming, people rarely used longjmp(), setjmp etc.. even though it is defined. There are good reasons to it. Once C++ exception is invented, people begin to abuse C++ exceptions, which boils down to use the setjmp and longjmp that historically never been used. That is BAD.
I agree that exceptions are often badly used, particularly smaller projects where the reasons for using them are often unclear. However, exceptions are in the c++ language for some very good reasons. There are certain very particular types of problems which require either exception handling or catastrophic program failure, namely: memory allocation failures (catch those news) and other failures that compromise the integrity of the environment.
In large applications (such as terabyte databases, cinematic 3d (modeling, special effects, and animation), modern computer games...) that may have very valuable information on them, you do not want catastrophic program failure. But, the problem is that you often cannot return an error code because the particular mechanism of returning may not function. For example, if a memory allocation failure occurs, it is likely a copy ctor call will fail as well. Exceptions let us to reverse down the call stack, allowing resource objects to free themselves as they distruct, in effect rolling back in a controlled manner the environment. This is much safer (particular if we give our destructors the strong guarantee), as it is mainly executions and resource deallocation. With exceptions, catastrophic program failures are mainly left to programming error, OS failure, or hardware failure (and many of these can be cleaned up with proper error checking programming practices and interfacing with the OS API).
*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/
"It's hard to believe in something you don't understand." -- the sidhi X-files episode
galathaea: prankster, fablist, magician, liar
-
January 25th, 2003, 11:21 AM
#11
Re: exceptions
Originally posted by galathaea
There are certain very particular types of problems which require either exception handling or catastrophic program failure, namely: memory allocation failures (catch those news) and other failures that compromise the integrity of the environment.
There's a "nothrow" version of new that returns a NULL pointer if you want but his point is that you should never throw yourself. He believes you're only required to work with exceptions when you *have* to (e.g., you're catching a 3rd-party exception for instance). I don't know how he expects operator overloading (and chaining) to report an error but that's just one issue. In any case, this was debated in the past so you can read his record on the subject but he's completely misguided IMO. I don't believe he's fully considered the issues and that's meant without insult. As I recall for instance, he once claimed that functions don't know who's actually responsible for catching an exception which is clearly false - the exception specification tells you that a function may throw and you can catch it if you want or let it propagate up the call stack - fundamentally that's no different than manually propagating a return code, a concept he clearly advocates. Here's just one lengthy thread but I believe there are others:
http://www.codeguru.com/forum/showth...ght=exceptions
-
January 26th, 2003, 11:38 AM
#12
There's a "nothrow" version of new that returns a NULL pointer if you want but his point is that you should never throw yourself. He believes you're only required to work with exceptions when you *have* to (e.g., you're catching a 3rd-party exception for instance). I don't know how he expects operator overloading (and chaining) to report an error but that's just one issue. In any case, this was debated in the past so you can read his record on the subject but he's completely misguided IMO. I don't believe he's fully considered the issues and that's meant without insult. As I recall for instance, he once claimed that functions don't know who's actually responsible for catching an exception which is clearly false - the exception specification tells you that a function may throw and you can catch it if you want or let it propagate up the call stack - fundamentally that's no different than manually propagating a return code, a concept he clearly advocates. Here's just one lengthy thread but I believe there are others:
Sef keep saying that I was misguided. But he failed say EXACTLY where and how I was misguided. No that is not true! I was never mis-guided. If any thing I guess you are confused yourself. The example you cited exactly shows so. It is exactly because that one has the liberty of either catch an exception or let it propagate to higher level, that it becomes unpredictable that who will catch an exception once it is thrown, or whether it will be catched at all. So am I not right in saying "functions don't know who's actually responsible for catching an exception". Why you think my claim is "clearly false"? Clearly you need to get the logic straight. I clearly don't know what's in your mind or how it works in your brain.
There are always good reasons (or rather excuses) in putting certain component into a language. There was a reason to put longjmp into C, there was also reason to put C++ exception into C++. The difference is peopel never ever abused the usage of longjmp, but people are clearly abusing C++ exceptions. In real world, the damages of C++ exceptions far exceeds its benefits.
Some people would argue that C++ exceptions are necessary to make it possible for constuctors and operators to report errors that otherwise has no mechanism to report. I say, why do you want to write a constructor or operator that can fail? If a task can be impelemented as an operator, then it should never fail. Do a = b + c ever fail? Do a = b*c ever fail? a = b/c may fail if C is zero. But do you prefer to wrape a = b/c with a try/catch, rather than simply check c before a=b/c? I would prefere the later.
a = b*c could fail to get the correct answer. But most cases you don't care, and if you care you would prefer to check the values yourself, instead of allowing the OS to throw an exception. Fortunately the OS never throws an exception if a=b*c overflows!!!
If the task could ever fail, and you care about the failure, then it should be implemented as a regular function with error return code, not as a constructor or operator.
-
January 26th, 2003, 02:22 PM
#13
Well...I am aware of these discussion ("Exceptions are evil" and so on) with you as well. As Sef already pointed out it is nothing wrong with stating your opinion about a specific language item as long as you mark it as your opinion. Unfortunately you always tend to write your responses as they would be the definitive word on a topic. This is quite not true.
As it is in this case, your opinion is a different one as many others. Exception handling is a powerful mechanism if implemented correctly. I do not want to argue that it can be misused as well. But there are thousands other mechanism in C++ and even C which can be misused as well...do you complain about them as well? Your problem is simpy that you always need to argue against everything that is not your beloved ANSI C.
And regarding you constructor question....did you ever write a constructor which needed to allocate memory by using 'new'?? How would I be able to get this error outside this without using exceptions? And even by using a common mechanism called 'RAII - Resource Acquisition is Initialization'...how would indicate that the resource could not be acquired within the constructor without throwing exceptions? There are many other examples but as many of us know you even do not care if someone points out valid arguments against your statements...so I will not go further here...
-
January 26th, 2003, 05:07 PM
#14
But he failed TO say EXACTLY where and how I was misguided
Ok. Let's do that but I implore you to *directly* address my response for a change.
It is exactly because that one has the liberty of either catch an exception or let it propagate to higher level, that it becomes unpredictable that who will catch an exception once it is thrown, or whether it will be catched at all. So am I not right in saying "functions don't know who's actually responsible for catching an exception". Why you think my claim is "clearly false"?
I have repeatedly used the term "exception specification" in these discussions. Do you know what these are? Please explain what the difference is between calling the following function using a return code or an exception. Like so (say, zero for success or an error code on failure):
Code:
int DoSomething()
{
}
or this alternative which does the same thing using an exception:
Code:
void DoSomething() throw(int)
{
}
You clearly advocate the first but the second is "evil". You even claim the second doesn't make it clear who is supposed to catch it. Why when they are fundamentally the *same*. The only difference is that the first returns an error using a return code, the second using an exception. The "exception specification" (do you clearly see the "throw(int)" clause at the end of the function) makes it clear to the caller that an "int" may be thrown. It's completely unambigous that the caller must be prepared to trap it. What is it about this that you don't get? How is that ambiguous compared to a return code? The same logic applies. When function 1 calls function 2, it clearly knows in both cases that failure is possible. The only difference is the mechanics at work. And in either case if the caller doesn't trap it well that's his fault. He's been warned and (for exceptions) the "std::terminate()" handler will be called (resulting in a call to "abort()" by default but you can override this with "set_terminate"). It's no less dangerous than you ignoring a return code and carrying on as if nothing happened. That can spell disaster also, frequently a lot more than just aborting the app altogether (since the app continues even after failure, resulting in potentially serious consequences). More programmers fail to do what *you* advocate (check return codes) which is potentirally much worse. At least if they ignore an exception, the app terminates by default which is frequently much safer (and again, you can even override this behaviour using "set_terminate").
Some people would argue that C++ exceptions are necessary to make it possible for constuctors and operators to report errors that otherwise has no mechanism to report. I say, why do you want to write a constructor or operator that can fail? If a task can be impelemented as an operator, then it should never fail. Do a = b + c ever fail? Do a = b*c ever fail? a = b/c may fail if C is zero. But do you prefer to wrape a = b/c with a try/catch, rather than simply check c before a=b/c? I would prefere the later.
Again, this is why people get so exasperated with you. Your claims are patently false. How do I do things your way using return codes if I *can't check for failure beforehand*:
Code:
FileStream << "Writes ok"' << "sector failure writing this";
You would have us not do it unless success is guaranteed which isn't even possible in some circumstances, is that right? And it matters not that using this type of syntax is frequently very convenient and often the most natural way to do things.
If the task could ever fail, and you care about the failure, then it should be implemented as a regular function with error return code, not as a constructor or operator.
Because Anthony says so? What about constructors that can possibly fail. Shall we set an error flag in the constructor and hope users check it. Or should we write an "Init()" function instead and hope users call it. And in either case, then what? Have all member functions check an "Init" flag to ensure the object was properly constructed? And none of this even addresses the benefits of exceptions over return codes, not the least of which is the ability to return rich error information. Or how about the countless if/else clauses required of return codes. Let's say my top-level function invokes a series of other functions where the only failure may occur due to a disk write when I'm 20 functions deep. In your scenario there will if/else clauses pulluting the code all the way down the call stack. Every function will have a return code that gets propagated all the way to the top (complicating some functions as well, since some will then have to designate an extra out argument because the return code itself is reserved for success or failure). The top-level function finally gets notified and pops up a message for the user (and what will the message say because only a return code is available - I may want to see the exact args at the point of failure). Using exceptions however, you can set up just one try/catch in the top-level function only. Now no return code is required for trapping success or failure and each function can either be void or use the return code for some other purpose as required. Now when the bottom function encounters the error, it simply throws an exception with complete failure info if desired, unlike in the return code case (without resorting to other methods). This is then automatically trapped at the top level function, with RAII automtatically cleaning up things along the way. No checking of return codes or even other try/catch blocks are required *anywhere* except the top-level function. Very clean. Very simple.
Are there potential drawbacks to exceptions. Of course. It's not a panacea and no system is perfect. Nor have I ever claimed they should replace return codes in all situations (or at all depending on what you're doing). That's in stark contrast to your own elitist views however, where exceptions are bad and evil and should *never* be used because Anthony says so. Such asbolute assertions are clearly false and in this case completely unreasonable.
-
January 27th, 2003, 01:50 AM
#15
And regarding you constructor question....did you ever write a constructor which needed to allocate memory by using 'new'?? How would I be able to get this error outside this without using exceptions? And even by using a common mechanism called 'RAII - Resource Acquisition is Initialization'...how would indicate that the resource could not be acquired within the constructor without throwing exceptions? There are many other examples but as many of us know you even do not care if someone points out valid arguments against your statements...so I will not go further here...
OK, let's talk about constructors that would fail. First, you CAN write constructors that would never fail unless catastrophy happens (like some one pulling the power plug or some memory gets over-written). You can postpone resource acquisition to later, after you have constructed the object. Further, even if the constructor can fail, you can report the error using a boolean within the object or even a static variable to indicate the error condition. There is no need to throw an exception.
Let's step back one step, let's say your constructor fails, and you do throw an exception. The question is WHO WILL catch the exception? Let's say you have a global instance of that object. Upon program loading, the constructor of that object gets called and it throws an exception. But it hasn't even started the main() function yet. So even if you have a big try/catch in the main(), you will still not be able to catch the exception!!!
I know about the RAII concept. Some one likes it. But I think it is a BAD idea. It mixes three things together: 1.Construction of an object. 2.Acquire resources that the object will be using. 3.Initialize the resource acquired. RAII attempts to do all three things at once.
The reality is you rarely want the three things to happen spontaneously. You may want to construct an object but postpone resource acquisition until when it is actually used.
You may re-acquire new resources or release old ones during the lifetime of an object, without destorying and reconstructing the object. Also, many times you do not want to initialize resource right upon acquisition, or simply is unable to initialize it yet at the moment of acquisition. So, object construction, resource acquisition, resource initialization. These three things rarely happen at the same time. RAII is an ill-formed idea that doesn't fit in the real world.
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|