quote: Original post by Kylotan
No, but it''s quicker and clearer to make certain parts of your program safe with auto_ptr than with new and delete.
OK, I''ll go with faster, slower code.
quote: Original post by Kylotan
You were implying that everything would be accessed through virtual functions in the base class rather than by downcasting to the derived class. I think your original post on this was not very clear so I''m sorry for the misunderstanding.
Hmm...no, if I said something that indicated that, then I''m sorry. I change my mind a lot (who would know?)
quote: Original post by Kylotan
quote:
--------------------------------------------------------------------------------
That is the whole purpose of using abstract classes -- you do not need to know the type, only whether a given class is derived from the abstract base class. Then why should you need to know the type when loading the classes?
--------------------------------------------------------------------------------
I am probably missing your point, but -something- has to know what type it is. Otherwise you cannot allocate the memory and call the correct constructor.
Yes, and that someone is the user of the library, not the library. That''s why I said that using class factories seemed to be transferring the responsibility from the user to the library writer unnecessarily. The user should load his/her classes from disk, not the library.
quote: Original post by Kylotan
<too much to list -- everything and anything about assertions>
Actually, all of the stuff that Eiffel has implemented that you mentioned regarding assertions could probably be done in C++. (You won''t get those pretty blue words, though.) I''ll concede that assertions do have a use, after all. I haven''t used them myself, because most debuggers allow you to run to a certain point in a program and then break into the code. Plus I step through most of my code at least once to make sure my logic is correct. I do disagree with much of MFC but thought it a typical example.
"In properly written code..." -- hmm...interesting...I thought it was subjective?
quote: Original post by Kylotan
quote:
--------------------------------------------------------------------------------
1) When you save the variables into the exception object, you copy by value. So it doesn''t matter where the variables are as they are saved from the calling code, which is -in- the try block (it has to be in the try block to throw()).
--------------------------------------------------------------------------------
Many bugs are down to obscure low-level errors, such as going over an array''s bounds, or a pointer to the wrong place. To call copy constructors on these potentially defective objects (after all, your program has just done something ''wrong'') is not always going to work, when it does it is not always going to be meaningful, and it is not always going to show you the problem.
You are also requiring a heavy handed approach to debugging: grab every variable we could possibly need to check and throw it down. How is this much better than the old routine in Basic of polluting the program with a load of ''print'' statements? How much work do you have to go to for that? It looks like an extremely unwieldy exception class, too. How would you implement that? Variable argument list? Or have to redefine the exception type each time you felt like checking different variables? Or every time you add a new variable to your routine that throws the exception?
1) It''s not a brute force approach -- it''s really rather elegant. Call exception::display() at the point of error, and it works just like an assertion. In circumstances where this is not plausible (fullscreen DX) you use logging, and this is where the variables might be good. Use ltoa() etc. in the constructor of the exception class and then just store the strings. Or use templates. Work smarter, not harder. (well, that''s partially correct)
2) I doubt anyone would write something like this pseudocode:
void do_something(object* p)
{
if( p == NULL )
throw exception(p->data);
}
Don''t you? Even if they did, it would cause an access violation and they would break into the code.
3) This is an example of a good use of those variables:
class direct_x
: public exception
{
public:
direct_x(HRESULT error_code, bool log_to_file)
: error_code(error_code), log_to_file(log_to_file) {};
virtual void display()
{
if(log_to_file)
log();
else
exception::display();
}
protected:
void log() { /* log to a file */ };
HRESULT error_code;
bool log_to_file;
};
Even if you catch it as an exception* and call display(), it still logs to a file. With this method, you would need only a few exception classes, and perhaps derive from direct_x to give more descriptive output.
quote: Original post by Kylotan
quote:
--------------------------------------------------------------------------------
2) How do you get to the information in calling functions from inside called functions when an assertion is called? You hit the break button on the compiler. Do the same when the message box is up in a catch() statement.
--------------------------------------------------------------------------------
Again, by that point several automatic variables have been deallocated, and merely copying them is not always sufficient. You are also suggesting that every function which can ''throw'' has its own ''catch'' block, which is not really the case, nor should it need to be. A 3rd, platform dependent, argument, is that I run programs outside of the debugger and only run the debugger once it has crashed/failed an assertion, by clicking the ''debug'' button that appears. That does not appear with exceptions.
You control where the message box pops up. You could just as easily call display() before throwing the function, so that you can break inside the try() block.
It''s a lot of code and effort compared to assert(a != 0). And doesn''t gain you very much. Cleanup, maybe, but I''ve never found that to be a problem during debugging.
1) You can choose, in your code, to display the exception as an assertion if you like!
2) You don''t have to have a catch statement in every function that has a try block.
3) It may be a lot of code, but Eiffel requires a lot of code too (behind the scenes). Encapsulate it with objects if you like.
4) Doesn''t gain me very much!?!?! *faints*
quote: Original post by Kylotan
Yes, and will often take an order of magnitude less time to write. On exactly the same token, software written in C++ does not run as fast as software written in assembly for exactly the same reasons: C++ is generic and does not take advantage of very specific asm instructions. You lose performance to gain in coding time and structure.
...
It is also like giving power tools to a 4 year old. Once past the low level details, you only need a subset of the functions to actually make the game. The rest can be implemented in something higher level, where you trade off a little performance for more productivity, fewer bugs, and a smaller, more well defined interface. You also do not have to own different compilers for every platform you are aiming at, since the VM is already there. Nor worry about functions that are not present on certain platforms, or require different syntax on different platforms. You can create a slimlined interface that inreases productivity.
1) Hmm...you need a higher level language because it will take less time to write and be faster, because of course C++ is faster to write in and thus slower because its easier and less specific than a higher level language like asm, and VMs are better because they are higher level than C++. ?? I''ll try again. VMs are good because they are higher level than C++ which is higher level than asm, and VMs have little or no performance impact which they should... ??? Please re-read that first paragraph that I quoted -- it makes no sense either with the rest of your arguments. I think I understand you to say that the trend is toward specific/generic software? No, that''s not it... I''ll keep trying...
2) Whoa. WHOA! Back up a little bit. There are some implications here that are incorrect. Let''s compare writing a VM and its implementations to writing a library and its implementations.
<comparison segment="VM writers">
The VM writer(s) must own compilers for the target platforms. The VM writer(s) must worry about functions that are not present on certain platforms, and different syntax on different platforms. The VM writer(s) must design a slimlined interface that increases productivity.
<comparison>
<comparison segment="library writers">
The library writer(s) must own compilers for the target platforms. The library writer(s) must worry about functions that are not present on certain platforms, and different syntax on different platforms. The library writer(s) must design a slimlined interface that increases productivity.
<comparison>
<comparison segment="VM users">
The VM user(s) must learn a new language subset.
<comparison>
<comparison segment="library uers">
The library user(s) must learn a new language subset.
<compatison>
Big difference, huh?
You can see that the differences lay not in the tasks to be done but their difficulty.Which is easier to write? A VM or a few DLLs? You say there are only two differences between the VM and the DLLs, and they are: a) implementations, b) language subsets.
a) The implementation of a DLL is fairly straitforward. Once you have planned the interface classes, you only have to fill in the code for each platform. It''s that simple. The implementation of a VM is much harder to write. You must design your own scripting language, including all the basic commands, and you must write a text parsing engine, an emulator, and then you must still fill in all the same code for the implementations on each of the platforms.
b) The language subsets produced are going to differ. Personally, I think it is the job of the programmer to implement the ideas of the designer, and not to design a system so that the designer can implement his own ideas. I think that is a responsibility of communication and does not call for a VM (design document....design document...) If a group can''t communicate, they''re not going to be able to write a good VM, so it''s pointless to create a VM to handle communication difficulties. If the programmer will be using the language, then it is (obviously) much more efficient to use the DLL approach.
I think that it''s much easier to write a generic class than a text parser/command interpreter. At least to me. Other people may indeed find it easier to write a VM than a class. Poor guys... *sniffles*
Yeah, I trust the industry experts about as far as I can throw them. Remember a little discrepancy back in the late 15th century? An idiot named Columbus thought the world was round. Fancy that. Everyone told him what the trend was. He just wouldn''t follow the popular thinking of the day... Poor guy... What I''m saying is that it''s quite possible for the majority to be wrong, and I think programmers (especially game programmers) have a tendency to jump off the deep end with work-arounds. All the time. I''ve seen implementations for VMs where the "pros" claimed syntax-checking and the like were mere annoyances and should be removed. I''ve seen many benefits that C++ provides re-implemented time and time again in the name of progress. And each time the re-implementation is infinitely worse than the original. It''s terrible. What''s worse is that newbies kiss the ground these experts walk on. The whole thing is kind of silly if you ask me.
The point of this discussion is that most of the advantages/disadvantages you listed have absolutely no bearing on VMs vs. DLLs. Conceptually, they''re the same: handled by the writer and hidden from the user. In short, libraries using abstract base classes provide all the scripting language you need while maintaining the things that SHOULD be standard, like memory management, syntax, etc. You gain benefit (in programmer time) from things being standard, and others being specific. That''s why we have APIs and the base language. The base language provides some things that are common to all programs, while APIs provide things specific to each type of program. It''s like an abstract class hierarchy -- some things are common and are placed in the base class, and some things are specific and placed in the derived classes.
Libraries using abstract base classes are the functional equivalent of a VM. However, libraries are easier to write; easier to maintain; easier to learn. There remains no justification for using a VM. Or is there? There are only two relevant points that you brought up concerning VMs: 1) portability, and 2) use by non-programmers. Personally, I think they are both irrelevant, but we''ll see.
#1 PORTABILITY
I argued against this last time, and the only thing you came up with is that you do not need a compiler for every target platform. I''m sorry, but that is what compilers were made to do. It''s what they do best; better than a lot of programmers; better than a VM. The time taken to write a VM could have been spent earning money to get the target platforms and compilers (most are either cheap or free). And you''d have a better game to distribute. Doh! Also, as I said before the VM writers must still have a compiler for every platform on which the VM will run.
#2 SCRIPTING
I already said before that VMs are just a work-around for what libraries already provide. Now you say that non-programmers should be able to write the game, to eliminate miscommunication between the programmer and the designer. I say that the benefit gained from any language is proportional to the experience in programming; the designers who do not program cannot produce as efficient a game as the programmers themselves. It is the responsibility of the programmer, the design documents, and the designer to iron out these things beforehand or set up a system whereby that might be easily accomplished. Don''t apply the band-aid of letting the final project suffer because of miscommunication. VMs are not cure-alls. Letting the designer code the game is just a poor work-around and as such an unnecessary waste of time. (BTW, A good program is flexible and extensible, and you should have no trouble adding features to it.)
Designers design; programmers program; compilers compile; virtual machines...?
quote: Original post by Kylotan
Why should an API differ from the language?
*blinks*
Why should software differ from the operating system? Why should the operating system differ from the BIOS? Why should the BIOS differ from the chip on which it is burned? Why are CPUs sold separate from the motherboard? Why use classes and functions? Why not assembly? Why classify and separate things at all?
Now you are you arguing against encapsulation. This is madness!
quote: Original post by Kylotan
If you want to deny what is -actually- happening, that is fine. But the real, observed trend is -away- from native code and towards scripting languages and engine-specific languages.
STL? no, that''s too generic and slow. DX? nah, not specific-enough. Platform-independent APIs (OpenML) founded and supported by large companies like Intel? nah, too far away from the problem domain...etc. If you want to deny the trend, then go right ahead.
People don''t always observe things correctly. And programmers are known for huge, inefficient work-arounds for tiny problems. Just because a solution requires more work and/or more intelligence doesn''t mean it is better than a simple solution. You said yourself that of two solutions, the simpler one is almost always better.
BTW, what is nested quoting?
- null_pointer
Sabre Multimedia