The question was about 'safety', like the classic problem with operators
Int operator (const Int& a, const Int& b) {
return Int(a.data + b.data);
}
Here, the syntax also allows you to return a reference
Int& operator(const Int& a, const Int& b) {
static Int tmp;
tmp.data = a.data + b.data;
return tmp;
}
but this is a very bad solution, even when the syntax is OK,
since when you add 'd = a + b + c', the temporal elements
will go crazy, because they will share/conflict the static 'tmp' variable.
The question then is, if you return a reference
int hello(int data) throw (MyExcept&) {
int a, b;
MyClass c;
....
throw MyExcept("bad data");
....
}
what will hapen with the temporal 'MyExcept("bad data")'?,
C++ is supposed to clean the entire function scope, including
the variables a,b,c, and all the temporal variables, which means
the exception instance will not necessary survive enough to
been caught. There is not warranty at least.
If you return a reference to a static global exception instance,
I thing there will be no problem, but I guess that in 99% of
the cases you return a "new" exception instance.
So, yes, the syntax is right, and it will compile in all the compilers,
and in many cases, depending of the compiler, it will run,
but will it run properly in all the cases?, or is a very
strange (and hard to find) seg. fault just waiting to happen.
Marcelo
William S Fulton wrote:
There isn't anything illegal about exception specifications that
contain references. The ISO C++ spec doesn't say anything about
restricting the types in the exception specification except that a
pointer or reference to an *incomplete* type is not allowed. The
reason seems to be that a temporary copy is made of the object being
thrown, thus the type must be complete in order to call the copy
constructor.
Anyway try the CVS version now, I've fixed it so that SWIG handles
references.
William
Oren Miller wrote:
It doesn't really matter either way, the same code is generated (at
least on gcc, for sure on MSVC since they ignore it completely :). I
always declared it as a reference because it seems to be better
documentation for people who aren't used to exceptions (there are
many out there!), and they tend to copy the value they see in the
specifier. Just seems sort of symmetrical I guess. I guess I'll
change my throw specifiers to get around this. In any case this
syntax is probably rare, but I've never encountered a compiler that
doesn't support it, so you may or may not want to as well. Thanks.
--oren
On May 28, 2004, at 10:44 PM, Marcelo Matus wrote:
Shouldn't your function be defined as
virtual void fromAdmin( const Message&, const SessionID& )
throw( FieldNotFound, IncorrectDataFormat, IncorrectTagValue,
RejectLogon) = 0;
ie, with no references '&' ?
The reference in the catching part makes sense
catch(FIX::FieldNotFound &_e) {
....
}
but does it make sense in the throw definition?
Marcelo
Oren Miller wrote:
Ok. I defined a typemap, but now I'm getting some different strange
behavior. Maybe you can tell me if I'm doing something wrong. So
I defined a simple ypemap like so:
%typemap(throws) FIX::FieldNotFound& {
SWIG_fail;
}
But that generated this, note the extra '&'
catch(FIX::FieldNotFound &&_e) {
{
SWIG_fail;
}
}
So I thought maybe I needed to change it to this:
%typemap(throws) FIX::FieldNotFound {
SWIG_fail;
}
But then it went right back to generating as before:
catch(...) {
throw;
}
Am I not doing this correctly?
On May 28, 2004, at 2:58 PM, William S Fulton wrote:
Doesn't SWIG emit a warning about not having a throws typemap?
This problem doesn't seem to be director specific. You can either
define a throws typemap for each of the different types in your
exception specification or define a generic SWIGTYPE& typemap for
all of them. You could base it off the SWIGTYPE throws typemap in
python.swg (SWIG-1.3.21).
William
Oren Miller wrote:
I have some virtual classes with throw specifiers that indicate
multiple possible exceptions, such as this one:
virtual void fromAdmin( const Message&, const SessionID& )
throw( FieldNotFound&, IncorrectDataFormat&,
IncorrectTagValue&, RejectLogon& ) = 0;
The code that is generated looks like this (for python):
try {
(arg1)->fromAdmin((FIX::Message const
&)*arg2,(FIX::SessionID const &)*arg3);
}
catch(...) {
throw;
}
catch(...) {
throw;
}
catch(...) {
throw;
}
catch(...) {
throw;
}
Now this does not cause any errors (at least not in gcc 3.2, I
can't speak for other compilers), but it does cause several
warnings (since ... should be the last thing to be caught, and
three of them are not last). With multiple directors which can
have several methods like this, the warnings can add up. Of
course this can make errors more difficult to spot. I would
suggest that the generated code either look like so:
try {
(arg1)->fromAdmin((FIX::Message const
&)*arg2,(FIX::SessionID const &)*arg3);
}
catch(FieldNotFound&) {
throw;
}
catch(IncorrectDataFormat&) {
throw;
}
catch(IncorrectTagValue&) {
throw;
}
catch(RejectLogon&) {
throw;
}
or just simply consolidated into:
try {
(arg1)->fromAdmin((FIX::Message const
&)*arg2,(FIX::SessionID const &)*arg3);
}
catch(...) {
throw;
}
On May 28, 2004, at 12:21 PM, David Beazley wrote:
Marcelo Matus writes:
Ok, the thing is that "C arrays mapping" is a strange case.
The problem with C arrays is that the have a known size, and
the '\0' ending char is just a coincidence, ie you can define
char hi_a [] = {'h','e','l','l','o'};
char hi_b [] = "hello";
and both will be different
sizeof(hi_a) -> 5
sizeof(hi_b) -> 6
strlen(hi_a) -> undefined
strlen(hi_b) -> 5
and in the python side you will get
hi_a -> 'hello'
hi_b -> 'hello\0'
note that you can also put '0' char in between
char hi_a [] = {'h','e',0,'l','o'};
sizeof(hi_a) -> 5
strlen(hi_a) -> 2
So, in your case, maybe is better to use
const char* const BeginString_FIX44 = "FIX.4.4";
since that will be properly understood in C,C++ and in the
python side
(and you don't need the std::string). In that case the use of
'strlen'
is explicit, and in the python side you will not see the '\0'
ending
character.
Any definitions of the form
char foo[N] = "whatever";
char bar[] = "whatever";
should *always* be treated as NULL-terminated strings by default in
SWIG. If someone wants different behavior than that, they should
write their own typemap to do it.
Why is this suddenly broken? I thought issues concerning C
character
arrays were resolved long ago.
-- Dave
_______________________________________________
Swig maillist - Swig@xxxxxxxxxxxxxxx
http://mailman.cs.uchicago.edu/mailman/listinfo/swig
_______________________________________________
Swig maillist - Swig@xxxxxxxxxxxxxxx
http://mailman.cs.uchicago.edu/mailman/listinfo/swig
_______________________________________________
Swig maillist - Swig@xxxxxxxxxxxxxxx
http://mailman.cs.uchicago.edu/mailman/listinfo/swig
_______________________________________________
Swig maillist - Swig@xxxxxxxxxxxxxxx
http://mailman.cs.uchicago.edu/mailman/listinfo/swig