Announcement: Be excellent to each other.


Caravel Forum : Caravel Boards : Development : In G++, verifying throw declarations match function code.
New Topic New Poll Post Reply
Poster Message
ErikH2000
Level: Legendary Smitemaster
Avatar
Rank Points: 2794
Registered: 02-04-2003
IP: Logged
icon In G++, verifying throw declarations match function code. (+1)  
Another request to the *Nixheads out there. Is there a tool that will check my code for uncaught exceptions? I.e. consider this code:

void MakeSomeTrouble(void) throw (CFileIOException)
{
  throw CNotExpectingThisException("Don't be a smug puppy.");
}


Now, in an ideal world, GCC/G++ would simply rebuke me for writing code that would throw an exception in MakeSomeTrouble() that doesn't match the throw declaration. And then fail the compile. But no, it instead compiles code that will generate a nasty SIGABORT. And these can take more than a little time to track down. Worse, a lot of exceptions are only thrown when errors occur that depend on rare conditions, i.e. somebody has the wrong sockets lib installed or wrong permissions are set on a certain file. So unit-testing exceptions to bring up all the SIGABORTs isn't really practical. The best I can do at this point, seems to be a rather careful eyeball check of all my functions to be exceedingly certain I'm not throwing something not covered in the function declaration.

Is there some compiler flag I can set that will improve this situation? Or is there some source code parsing tool that verifies throw declarations match code of the function and its callees?

-Erik

____________________________
The Godkiller - Chapter 1 available now on Steam. It's a DROD-like puzzle adventure game.
dev journals | twitch stream | youtube archive (NSFW)
10-27-2006 at 08:44 PM
View Profile Send Email to User Show all user's posts This architect's holds Quote Reply
AlefBet
Level: Smitemaster
Rank Points: 979
Registered: 07-16-2003
IP: Logged
icon Re: In G++, verifying throw declarations match function code. (+5)  
The general consensus is that throw specifications are useless in C++. Most of the people who use them will only ever bother with the empty throw() clause and none others. And even then, it's usually only on functions where throwing an exception is genuinely dangerous, such as destructors, or member functions for exception objects.

The exception specification problem is a nasty one to solve. I've spent a lot of time thinking about proposals for how it could be solved. I even came up with an idea and suggested it to the C++ forum, which then received a lot of critical feedback. My current evaluation is that it's just not practical, at least not with what is known now.

What follows is a rather lengthy treatise on exception handling and specifications. If the subject bores you, feel free to ignore me.

I expect you're thinking along the lines of Java's checked exception specificiations, right? C++ adopted a somewhat different philosophy of exceptions from Java which makes specifications not work very well. In the Java method for dealing with exceptions, you need to know exactly what rare conditions might occur when your function is called, and either handle them all locally or declare them to be thrown from your function. From one point of view this makes sense. If your function might exit by throwing an exception rather than returning success, it would be nice for the caller to know this, and to know what types of failures might occur so it can plan for them. It ought to be at least part of the documentation, and preferably enforced by the language. So Java requires you to specify these things and checks your specification against your implementation. Certainly makes sense to me.

However, this has a few wrinkles in it. First of all, the exception checking mechanism is imperfect. It will generally spot unhandled exceptions, but it may have a tendency to spot exceptions that can't actually occur. For example, consider this:
#include <iostream>

class NegativeArgumentException { };

void pass_me_a_positive(double x) throw(NegativeArgumentException) {
    if (x<0)
        throw NegativeArgumentException();
    // ...
}

int main() {
    double x;
    std::cin >> x;
    x*=x;
    pass_me_a_positive(x);
}
Under the Java philosophy, pass_me_a_positive() might throw NegativeArgumentException, so main() should be required to either catch such an exception or declare that it throws the exception. However, the programmer knows that the exception never will be thrown because the logic of the program won't allow for it. But the Java rules would still have him putting a dummy try{}catch(){} block in to appease the code analyzer.

Naturally, that's somewhat of a contrived example. But there are other issues. For example, consider polymorphism. Suppose you have a class something like this:
class FileError { };
class NetworkError { };
class Remote_Object {
public:
    virtual std::string getvalue() const throw(FileError, NetworkError) =0;
};
where Remote_Object represents a handle of some sort for getting a value from some remote source. This remote source might represent a file on disk or a server somewhere on the network, so when you try to get the value, the file system might return an error, or a network error might happen, so you may be unable to retrieve the value. The code that actually uses the class won't usually care why there was a failure, though. Usually, the user of the class will want to just detect the exception and abort the current operation, passing the exception further out until the main() routine catches any uncaught exception, prints an error message, and quits or retries or does something else.

Now, though, suppose you want to create a new type of Remote_Object like this:
class UserGivenValue : public Remote_Object {
public:
    class UserAbortedEntry { };
    virtual std::string getvalue() const throw(UserAbortedEntry);
};
Unfortunately, under the Java model, this won't work, because a derived override is not allowed to throw any exceptions that the base function didn't declare. So, the writer of UserGivenValue can try to do a number of clunky things. He can translate the UserAbortredEntry object into a FileError object or a NetworkError object and throw that instead, but it's not really either of those types of errors. Or he can catch the UserAbortedEntry object and just ask the question over and over until the user condescends to give a value, but that's more like putting yourself in denial about the fact that the user didn't want to enter a value in the first place. Or he can modify the base class (and any functions that use the base class), but this only works if he is free to modify that code and results in a change of the class's specification, which could lead to problems with other applications using this class. And the tragedy is that the whole thing probably would have worked just fine if the language had allowed the UserAbortedEntry exception to be thrown in the first place since the user of the class usually doesn't care why the failure happened, only that it did, and the main routine is catching everything anyway.

This code example also wouldn't work under the C++ model of exception specifications, because it has a similar limit about allowing derived classes to throw exceptions that the base doesn't declare. In the C++ case, the author would have the option of throwing a UserAbortedEntry object anyway, but not declaring it. This is hardly better, since the result is a call to unhandled_exception() which usually calls terminate(). But in C++, the default exception specification is to allow anything to be thrown. So if all the exception specifications are simply removed, everything works fine again.

The C++ philosophy towards exceptions is that exceptions correspond to exceptional circumstances in execution. Therefore, code should usually be written with the common case of execution in mind, and enough exception handling code added in to properly handle the unusual circumstances, but no more than necessary for good recovery. If code is written this way, and then otherwise written so that operations in general may fail unless guaranteed not to, exceptions mostly stay out of the way. To that end, exception specifications are made optional and not checked. (Those two go together by the way, you can't make them checked without making them required. You can't check a function's exception spec without having the specs available for the functions it calls.) When you add exception specification code to all functions, you're one step closer to the old method of checking return values for error conditions.

That philosophy about exceptions also happens to be my philosophy, but if you don't agree with it, there's nothing wrong with that as long as you realize that is more or less why C++ is the way it is WRT exceptions.

Anyway, the bottom line is that a tool to actually check and formally verify C++ exception specifications would be quite a sophisticated project. Not impossible, but I doubt it's been done. And if it has, chances are it would occasionally warn about an exception that would never occur anyway. (Actually, probably more than occasionally, since C++ has exceptions for domain errors relating to improperly passed arguments.)

I guess the short answer is, no, there isn't a flag to allow g++ to check exception specs, and I doubt there's another program written currently that would do the job instead.

____________________________
I was charged with conspiracy to commit jay-walking, and accessory to changing lanes without signaling after the fact :blush.

++Adam H. Peterson
10-27-2006 at 11:15 PM
View Profile Send Private Message to User Send Email to User Visit Homepage Show all user's posts Quote Reply
ErikH2000
Level: Legendary Smitemaster
Avatar
Rank Points: 2794
Registered: 02-04-2003
IP: Logged
icon Re: In G++, verifying throw declarations match function code. (+1)  
Man, I could not have gotten a better answer to this question. Thanks, Adam.
AlefBet wrote:
I expect you're thinking along the lines of Java's checked exception specificiations, right?
Yes, you read me like a book. I had just returned to C++ after a stint in Java and was feeling all gung-ho on using exceptions in the Java style, where all the possible ways a function can fail are up there in the throw declaration. I realize there are shortcomings, but it still seemed like a nice design. I get fatigued from propagating error return codes all over the place. A few needlessly verbose try...catch blocks here and there and some occasional inefficiency in executing throw code seemed a small price to pay. :)
C++ adopted a somewhat different philosophy of exceptions from Java which makes specifications not work very well.
I believe I understand your explanation. I guess the ability to give specific exceptions in the throw declaration seems like a terrible red herring. It would be better to just have the compiler bark at me for being deluded about my ability to do something useful with those declarations. In MSVC, if I declare:

void SomeFunc() throw(CSpecificException)


...it is compiled in the exact same way as...

void SomeFunc() throw(...)


...which made me really irritated, especially when I was incorrectly attributing the limitation to laziness on Microsoft's part. But apparently G++ is even more misleading, because code like this:

void SomeFunc() throw(CSpecificException)
{ throw CWrongException; }


...just produces a SIGABORT (or call to unhandled_exception() as you say) when the code executes. It doesn't even matter if I have a suitable catch waiting in the caller of SomeFunc(), i.e.

void SomeFunc() throw(CSpecificException)
{ 
  throw CWrongException(PROGRAMMER_IS_A_FRACKING_IDIOT);
}

void CallSomeFunc()
{
  try { SomeFunc(); } catch(CWrongException) { }
}


...the above code still causes the SIGABORT when CWrongException is thrown. So considering that, regardless of what you feel exceptions should be used for, does it not seem that:

A. The compiler should either enforce the exception mismatch completely at compile-time, (i.e. there is no way this exception could ever be caught == BIG FAT COMPILER ERROR) or just allow the exception to be caught at run-time.

B. If there won't be any useful enforcement of specifying exceptions in the throw declaration, then the language ought not to allow specifying them. (If we wanted to merely document which exceptions a function might throw, we could just use comments.) It would be much less misleading to just allow semantics at compile-time to specify either that a function may throw any kind of exception or a function will not throw any exceptions. I.e. allow "throw()" and "throw(...)", but not "throw(CSomeSpecificException)".

I'm no language expert, but this part of C++ just seems to not be thought out very well. I admit it's likely I don't understand something yet.

Adam, as for what I'll do with my code... I think I'll just change all my functions to have either "throw()" or "throw(...)". And move the list of specific exceptions into comments. Then I guess it would be useful to find a tool that parses source to determine what all exceptions might be thrown down the calling chain. Admittedly, that's a tricky thing to write, but it can't be that hard. NetBeans IDE, for example, does it for Java code where you can select a block of code and ask NetBeans to insert appropriate exception handlers. I know, I know... "then why don't you go write it, smart guy?"

-Erik

____________________________
The Godkiller - Chapter 1 available now on Steam. It's a DROD-like puzzle adventure game.
dev journals | twitch stream | youtube archive (NSFW)
10-28-2006 at 12:42 AM
View Profile Send Email to User Show all user's posts This architect's holds Quote Reply
AlefBet
Level: Smitemaster
Rank Points: 979
Registered: 07-16-2003
IP: Logged
icon Re: In G++, verifying throw declarations match function code. (+2)  
ErikH2000 wrote:
In MSVC, if I declare:

void SomeFunc() throw(CSpecificException)


...it is compiled in the exact same way as...

void SomeFunc() throw(...)


...which made me really irritated, especially when I was incorrectly attributing the limitation to laziness on Microsoft's part. But apparently G++ is even more misleading, because code like this:

void SomeFunc() throw(CSpecificException)
{ throw CWrongException; }


...just produces a SIGABORT (or call to unhandled_exception() as you say) when the code executes. It doesn't even matter if I have a suitable catch waiting in the caller of SomeFunc(), i.e.

void SomeFunc() throw(CSpecificException)
{ 
  throw CWrongException(PROGRAMMER_IS_A_FRACKING_IDIOT);
}

void CallSomeFunc()
{
  try { SomeFunc(); } catch(CWrongException) { }
}


...the above code still causes the SIGABORT when CWrongException is thrown.
Yes, in this respect MSVC is non-conforming to the C++ Standard. However, it is non-conforming in a way that almost nobody who knows the full story really cares all that much about. I almost prefer the MSVC way to doing it so that non-empty throw() clauses could at least be used as documentation. As they are, they're usually exactly not what you want.
So considering that, regardless of what you feel exceptions should be used for, does it not seem that:

A. The compiler should either enforce the exception mismatch completely at compile-time, (i.e. there is no way this exception could ever be caught == BIG FAT COMPILER ERROR)
That would be nice. Unfortunately, it's never going to happen, I don't think. You've got issues with polymorphism, with templates, and with exceptions that don't actually occur, and they're compounded to some extent by C++'s separate compilation model. And it would essentially make domain_error exceptions useless and annoying.
or just allow the exception to be caught at run-time.

B. If there won't be any useful enforcement of specifying exceptions in the throw declaration, then the language ought not to allow specifying them. (If we wanted to merely document which exceptions a function might throw, we could just use comments.) It would be much less misleading to just allow semantics at compile-time to specify either that a function may throw any kind of exception or a function will not throw any exceptions. I.e. allow "throw()" and "throw(...)", but not "throw(CSomeSpecificException)".
I think the theory about why they work like they do is that on the occasion that you have an exception specification, you can count on it absolutely. This is important, for example, with the member functions of exception objects. If you have a code snippet like this:
try {
    // ....
} catch (const std::exception &e) {
    std::cerr << e.what() << std::endl;
}
it is nice to know that what() is declared like so:
namespace std {
    class exception {
    public:
        virtual char *what() const throw() =0;
    };
}
because you have some guarantee (however draconian) that you won't have to worry about what() throwing an exception while you're vulnerable in your catch(){} block. (Similar logic for when used on destructors.) If some library maker screws that up, their test suite should crash hard, alerting them to the problem.

That type of guarantee is mostly only good for the no-throw specification, which sort of adds some credence to Microsoft's (non-conforming) implementation.
I'm no language expert, but this part of C++ just seems to not be thought out very well. I admit it's likely I don't understand something yet.
You won't get a serious argument from me, or from most of the people on comp.lang.c++ either, I expect. That's why I say the general consensus is that exception specs in C++ are mostly useless and seldom used.
Adam, as for what I'll do with my code... I think I'll just change all my functions to have either "throw()" or "throw(...)". And move the list of specific exceptions into comments.
My advice would be to leave exception specs off completely, except for comments. (I believe a few C++ programmers have the habit of adding throw specs in comments after their functions.) You may want to add no-throw() specs on functions that you know are genuinely dangerous for throwing exceptions, such as possibly destructors, but if you merely think they shouldn't throw and don't necessarily rely on it, I'd just document that in comments instead. A throw(...) spec is really redundant and extra typing for no real information.

Of course, it's up to you.
Then I guess it would be useful to find a tool that parses source to determine what all exceptions might be thrown down the calling chain. Admittedly, that's a tricky thing to write, but it can't be that hard.
Well, like I say, I believe it can be that hard, but probably not impossible. If you do, you'll need to run it in the context of the entire project in order to address the polymorphism issue (which means you might need to revalidate the same module in a different project if you inherit from it).
NetBeans IDE, for example, does it for Java code where you can select a block of code and ask NetBeans to insert appropriate exception handlers.
That sounds handy. I wonder how they handle the polymorphism angle. If you have access to it, could you test it out for me? Could I give you a few Java modules that exhibit the problem and have you tell me what it does? My guess is that whatever else it automatically does for you, it falls on the programmer's shoulders to get the base class's method "throws" clause right.

____________________________
I was charged with conspiracy to commit jay-walking, and accessory to changing lanes without signaling after the fact :blush.

++Adam H. Peterson

[Last edited by AlefBet at 10-28-2006 02:00 AM]
10-28-2006 at 01:44 AM
View Profile Send Private Message to User Send Email to User Visit Homepage Show all user's posts Quote Reply
ErikH2000
Level: Legendary Smitemaster
Avatar
Rank Points: 2794
Registered: 02-04-2003
IP: Logged
icon Re: In G++, verifying throw declarations match function code. (0)  
AlefBet wrote:
My advice would be to leave exception specs off completely, except for comments. (I believe a few C++ programmers have the habit of adding throw specs in comments after their functions.) You may want to add no-throw() specs on functions that you know are genuinely dangerous for throwing exceptions, such as possibly destructors, but if you merely think they shouldn't throw and don't necessarily rely on it, I'd just document that in comments instead.
One factor to add into this is that my code compiles under MSVC as well as G++. And under MSVC, there is at least some compile-time checking of throw() versus throw(...) specifiers. I admit, I'd have to do some tests to see exactly what it allows or doesn't allow. Also, it is much easier for me to keep track of which functions are specified throw() or throw(...) than it is to keep track of which types of exceptions are thrown. I.e. if I change which exceptions are thrown by code in some deep-down function that was already declared with a throw(...) specifier, I don't need to reexamine every caller of that function to make sure the throw specifiers still match or exceptions are caught.
A throw(...) spec is really redundant and extra typing for no real information.
I don't know how it is in G++, but in VC, the throw behavior when a function has no specifier can change based on how compiler flags are set. By adding "throw(...)" I remove ambiguity, and I can avoid some problems if my code is reused in a different project with the compiler flags set differently.
That sounds handy. I wonder how they handle the polymorphism angle. If you have access to it, could you test it out for me? Could I give you a few Java modules that exhibit the problem and have you tell me what it does? My guess is that whatever else it automatically does for you, it falls on the programmer's shoulders to get the base class's method "throws" clause right.
Sure, post the java file or e-mail it to me. I'll try it out Monday. I don't know how NetBeans IDE does its magic, but I suspect it is running the java compiler in a background thread and parsing the output for names of exceptions that show up as compiler errors. So in this case, it's probably only going to pick up checked exceptions and not unchecked exceptions (derived from RuntimeException).

-Erik

____________________________
The Godkiller - Chapter 1 available now on Steam. It's a DROD-like puzzle adventure game.
dev journals | twitch stream | youtube archive (NSFW)
10-28-2006 at 02:37 AM
View Profile Send Email to User Show all user's posts This architect's holds Quote Reply
AlefBet
Level: Smitemaster
Rank Points: 979
Registered: 07-16-2003
IP: Logged
icon Re: In G++, verifying throw declarations match function code. (0)  
ErikH2000 wrote:
One factor to add into this is that my code compiles under MSVC as well as G++. And under MSVC, there is at least some compile-time checking of throw() versus throw(...) specifiers.
Really? I wasn't aware of that. Is there a MSDN page or something you could point me to so I could get more info on that? I was under the impression to the contrary, but I haven't used MSVC regularly for about four or five years.
Also, it is much easier for me to keep track of which functions are specified throw() or throw(...) than it is to keep track of which types of exceptions are thrown.
Ah, now you're starting to hit near one of the reasons I prefer the C++ way to the Java way. I have a tendency to throw dozens of different exception types, and it's nice to not have to list them all in the throw clauses.
A throw(...) spec is really redundant and extra typing for no real information.
I don't know how it is in G++, but in VC, the throw behavior when a function has no specifier can change based on how compiler flags are set.
I'd be interested in an MSDN page on that too, if you happen to know of one. If it's not already at your fingertips, though, don't worry about it.
By adding "throw(...)" I remove ambiguity, and I can avoid some problems if my code is reused in a different project with the compiler flags set differently.
I believe that's non-conforming behavior. But there's nothing that says a conforming compiler has to conform regardless of compiler options (as long as there exists a conforming setting).
Sure, post the java file or e-mail it to me. I'll try it out Monday. I don't know how NetBeans IDE does its magic, but I suspect it is running the java compiler in a background thread and parsing the output for names of exceptions that show up as compiler errors. So in this case, it's probably only going to pick up checked exceptions and not unchecked exceptions (derived from RuntimeException).
Okay, here are three modules below. I'd like to see if it finds the throw clauses that are commented out.
import java.lang.Exception;
class user {
	public static void main(String[] args) {
		try {
			derived d=new derived();
			d.f1(1);
			d.f2(1);
			d.f1(2);
			d.f2(2);
		} catch (Exception e) {
			System.out.println("caught");
		}
	}
}


import java.lang.Exception;
abstract class base {
	public abstract int f1(int nottwo);// throws Exception
	public int f2(int nottwo) { //throws Exception
		return nottwo;
	}
}


import java.lang.Exception;
class derived extends base {
	public int f1(int nottwo) { // throws Exception
		if (nottwo==2)
			throw new Exception();
		return nottwo;
	}
	public int f2(int nottwo) { // throws Exception
		if (nottwo==2)
			throw new Exception();
		return nottwo;
	}
}


____________________________
I was charged with conspiracy to commit jay-walking, and accessory to changing lanes without signaling after the fact :blush.

++Adam H. Peterson
10-28-2006 at 03:00 AM
View Profile Send Private Message to User Send Email to User Visit Homepage Show all user's posts Quote Reply
Syntax
Level: Smitemaster
Rank Points: 1218
Registered: 05-12-2005
IP: Logged
icon Re: In G++, verifying throw declarations match function code. (0)  
AlefBet wrote:
The general consensus is that throw specifications are useless in C++...
Wow... I wish I was funny enough to accumulate enough mod points to mod that up for the rest of the day. Excellent!
10-28-2006 at 09:37 AM
View Profile Send Private Message to User Show all user's posts Quote Reply
AlefBet
Level: Smitemaster
Rank Points: 979
Registered: 07-16-2003
IP: Logged
icon Re: In G++, verifying throw declarations match function code. (+1)  
I was reading up on Visual Studio's behavior with the empty throw() spec, and what I found gives me some concern. Apparently the copmiler treats it as being equivalent to a __declspec(nothrow). There's plans for changing that behavior in the future to a bona fide enforcement, but for the time being that behavior is quite different from what other compilers are likely to do.

__declspec(nothrow) hints the compiler that the function should never throw an exception. This can be an optimization, so the compiler can remove exception propagation code from the generated function. What this ends up giving us, though, is that if the function does actually throw an exception, undefined behavior will result. So, unexpected() won't actually be called, and the application may die a gruesome death, but the exact manner of that death (or whether it occurs) is not specified.

This is different from other compiler implementations (and possibly future versions of MSVC), where the behavior of throw() is actually a pessimization, requiring the compiler to effectively wrap the body of the function in an implicit try...catch block to call unexpected() in the unlikely event of an exception occurring where it shouldn't. So a throw() spec under MSVC creates code that may be marginally faster and less safe, and on other compilers creates code that may be marginally slower and still not very useful.

If it were me, I'd rather have an unusual exception like std::bad_alloc (which might be thrown when a user runs low on memory) print a useful error message, if the alternative is unspecified behavior. I expect it would be easier to track down the cause of such crashes. Even if (or perhaps especially if) the same code is compiled with both MS- and non-MS-compilers, I'd leave off even empty throw() specs.

So there are some more of my thoughts on the issue for you all.

____________________________
I was charged with conspiracy to commit jay-walking, and accessory to changing lanes without signaling after the fact :blush.

++Adam H. Peterson
10-28-2006 at 09:36 PM
View Profile Send Private Message to User Send Email to User Visit Homepage Show all user's posts Quote Reply
ErikH2000
Level: Legendary Smitemaster
Avatar
Rank Points: 2794
Registered: 02-04-2003
IP: Logged
icon Re: In G++, verifying throw declarations match function code. (+1)  
AlefBet wrote:
ErikH2000 wrote:
One factor to add into this is that my code compiles under MSVC as well as G++. And under MSVC, there is at least some compile-time checking of throw() versus throw(...) specifiers.
Really? I wasn't aware of that. Is there a MSDN page or something you could point me to so I could get more info on that? I was under the impression to the contrary, but I haven't used MSVC regularly for about four or five years.
I can't find docs for it, but there is some limited checking. The following code won't compile because of the exception-throwing code that conflicts with "throw()" specifier:

void ShouldNotThrow() throw()
{
  throw 1;
}


This was encouraging to me, but it's still very easy to write mismatched exception code which isn't caught at compile-time. If you call throwing functions from a no-throw function, it won't be caught a compile-time.

void WillDefinitelyThrow() throw(...)
{ 
  throw 1;
}

void ShouldNotThrow() throw()
{
  WillDefinitelyThrow();
}


So I may take your advice and get rid of throw specifiers altogether. Too bad.
I don't know how it is in G++, but in VC, the throw behavior when a function has no specifier can change based on how compiler flags are set.
I'd be interested in an MSDN page on that too, if you happen to know of one. If it's not already at your fingertips, though, don't worry about it.
Here you go!

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vclang/html/vclrfexceptionspecifications.asp

Okay, here are three modules below. I'd like to see if it finds the throw clauses that are commented out.
Naw, it doesn't. If it did, don't you think it would be maybe getting a little too clever for itself? :) NetBeans IDE flags the two throw statements as errors ("unreported exception java.lang.Exception; must be caught or declared to be thrown"). This text matches exactly what I get from output when running javac, so I'm 99% sure they are running the compiler in the background to display error messages before the user compiles. And when they generate try catch blocks from a selected area of text, parsing hidden compilation errors would be enough to learn which exceptions need to be caught. So it looks like the really involved code for determining if exceptions will be caught is all down in the compiler.

-Erik

____________________________
The Godkiller - Chapter 1 available now on Steam. It's a DROD-like puzzle adventure game.
dev journals | twitch stream | youtube archive (NSFW)
11-01-2006 at 06:28 PM
View Profile Send Email to User Show all user's posts This architect's holds Quote Reply
New Topic New Poll Post Reply
Caravel Forum : Caravel Boards : Development : In G++, verifying throw declarations match function code.
Surf To:


Forum Rules:
Can I post a new topic? No
Can I reply? No
Can I read? Yes
HTML Enabled? No
UBBC Enabled? Yes
Words Filter Enable? No

Contact Us | CaravelGames.com

Powered by: tForum tForumHacks Edition b0.98.8
Originally created by Toan Huynh (Copyright © 2000)
Enhanced by the tForumHacks team and the Caravel team.