# Thread: Use of Exceptions.

1. ## Use of Exceptions.

Hey guys, I am trying to understand this code our lecturer wrote..
I have understood other use of exceptions, but I can't understand his
So I need your help

Code:
```#pragma once

#include <exception>
#include <iostream>
#include <fstream>
#include <exception>
using namespace std;

class MatrixException: public exception
{
public:
virtual const char * what() const throw();
};

class DynamicMatrix
{
public:
float * m;
int rows, cols;
public:
DynamicMatrix(int rows, int cols);
DynamicMatrix(DynamicMatrix & m);
~DynamicMatrix(void);
void set(int row, int col, float val);
float get(int row, int col) const;
DynamicMatrix operator*(const DynamicMatrix & matrix) const throw (MatrixException);
DynamicMatrix operator=(const DynamicMatrix & matrix);

friend ostream &operator<<(ostream &stream, DynamicMatrix v);
friend istream &operator>>(istream &stream, DynamicMatrix &v);

};
#include "DynamicMatrix.h"
#include <iostream>
using namespace std;

const char * MatrixException::what() const throw()
{
return "Could not multiply these matrices";
}

DynamicMatrix DynamicMatrix::operator*(const DynamicMatrix & matrix) const throw (MatrixException)
{
if (this->cols != matrix.rows)
{
throw MatrixException();
}

DynamicMatrix ret(rows, matrix.cols);
for (int row = 0 ; row < rows ; row ++)
{
for (int col = 0 ; col < matrix.cols ; col ++)
{
float value = 0.0f;
for (int i = 0 ; i < matrix.cols ; i ++)
{
value += get(row, i) * matrix.get(i, col);
}
ret.set(row, col, value);
}
}

return ret;
}```
I have been able to understand that he defined a MatrixException class which overrides the what() function in the base class so that he can change its use for his own purpose..
what I don't understand is how it is declared?
Code:
`virtual const char * what() const throw();`
virtual, to tell us he is overriding the what() from the base class.
const char * i think means what() returns a pointer to a constant character(or first character in a string).
const throw() I don't know what that means...
I have seen throw, but throw() - it is a function now?
what does const throw() after what() even mean? so what does the definition above mean?

Code:
```     const char * MatrixException::what() const throw()
{
return "Could not multiply these matrices";
}```
so there he is defining how the what() should be used..but what does the const throw() beside it mean? haha
then here he does

Code:
```DynamicMatrix DynamicMatrix::operator*(const DynamicMatrix & matrix) const throw (MatrixException)
{
if (this->cols != matrix.rows)
{
throw MatrixException();
}

DynamicMatrix ret(rows, matrix.cols);
for (int row = 0 ; row < rows ; row ++)
{
for (int col = 0 ; col < matrix.cols ; col ++)
{
float value = 0.0f;
for (int i = 0 ; i < matrix.cols ; i ++)
{
value += get(row, i) * matrix.get(i, col);
}
ret.set(row, col, value);
}
}

return ret;
}```
there he passes the MatrixException class (I don't think it is an object anyways) to the throw function..but how does link with the const throw(MatrixException) in the function declaration?

when he does this throw MatrixException() what happens then?
Can anyone explain this...s***
thanks!

2. The virtual keyword means that it's a virtual function.
The "const" means it's a constant function (ie, it does not modify the class's internal state).
The "throw()" part means that the function does not throw any exceptions.
The "throw(MatrixException)" means the function may throw a MatrixException object.
Note that the is purely information and not enforced at runtime. It is not widely implemented in compilers, either, making it rather redundant other than for information purposes, unfortunately. Microsoft's compiler, for example, ignores the keyword entirely.

3. For the original posted, it is better not to use exception specifications because they can't be trusted to be portable. (Elysia is exactly right about that bit.) Instead, manually add code to trap exceptions that shouldn't be propagated and call `std::terminate'. (You can't trust `std::unexpected' as that is a "noop" on some platforms.)

That said, depending on the platform, adding a `throw()' is sometimes required and other times is very definitely not allowed. This is almost always related to using function objects with the "STL". Even for the empty exception specification you should protect yourself from problems by using a macro to selectively change the signature for those cases where compilers differ.

Note that the is purely information and not enforced at runtime.
That's wrong; the standard requires that `std::unexpected' be called in the face of an unexpected exception. That check for an unexpected exception is done at runtime.

It is not widely implemented in compilers, either, making it rather redundant other than for information purposes, unfortunately.
Unfortunately, it really is widely implemented, and just as widely misused. (It doesn't mean what most people think it means.) It just happens that it is often implemented in a non-standard conforming way.

Microsoft, for example, doesn't really ignore exception specifications; it simply implements them in a non-standard conforming way that looks as if it is ignored. (If memory serves, it will never call `std::unexpected' and will issue a warning with `throw()' in some cases but not others.)

I'm only bringing that up because the behavior is actually worse than simply always ignoring an exception specification.
[/Edit]

Soma

4. Ah, memory serves me wrong. It's not actually enforced at compile time, which you'd expect from a type-safe language like C++, and funnily enough, one of the things Java got right.

5. ...
so, to prevent a function from throwing an exception, I add a throw() after the function declaration and definition? jeez, how odd.
But when throw MatrixException() gets executed..how does it call MatrixException.what()? Nothing in the code tells me how it is called...

6. so, to prevent a function from throwing an exception, I add a throw() after the function declaration and definition?
O_o

See here:

just as widely misused
and here:

It doesn't mean what most people think it means.
Adding a "no throw" exception specifier (`throw()') does not prevent the function from throwing an exception; it also doesn't prevent functions that the marked function calls from throwing an exception. All it does is prevent an exception that is thrown from propagating along the call stack beyond the marked function. (And that's only if the compiler honors the standard.) Further more, if the marked function or a function that that function calls does throw an exception, the standard function `std::unexpected' may or may not be called depending on whether or not the platform honors the standard.

Really, you are better off pretending that exceptions specifications don't exist until you come across a platform that forces them to be used in certain cases. Until them, just don't use them.

Nothing in the code tells me how it is called...
It will be called, if it is called at all, at the point that the exception is caught.

Soma

7. ok man thanks very much.

Popular pages Recent additions