Re: svn commit: r565959 - /incubator/stdcxx/trunk/etc/config/src/EXTERN_C_EXCEPTIONS.cpp

2007-08-22 Thread Martin Sebor

Travis Vitek wrote:
 


Martin Sebor wrote:

Farid Zaripov wrote:


I've just tried to declare and define __rw_once with throw(...)
exception specification and compiler doesn't issues warning in
that case.


Yes, but the documentation linked to explicitly says...

  Explicit exception specifications are not allowed on C functions.
  [http://msdn2.microsoft.com/en-us/library/wfa0edys(VS.80).aspx]

I tested, it does compile, and the destructors are getting called as
they should when an explicit throw(...) spec is added to the C linkage
function. That said, I cringe at the thought relying on behavior that is
documented to not work or is not supported.


FWIW, I looked to see if throw(...) is being used by any projects
out there and what for. I've found a few but none very helpful. In
particular, I found only one extern C function with throw(...),
and that's in some toy example. All the other hits point to C++
functions:

http://www.google.com/codesearch?q=throw%5C+*%5C%28%5C+*%5C.%5C.%5C.%5C+*%5C%29+lang%3Ac%2B%2B

Martin


Re: svn commit: r565959 - /incubator/stdcxx/trunk/etc/config/src/EXTERN_C_EXCEPTIONS.cpp

2007-08-21 Thread William A. Rowe, Jr.
Farid Zaripov wrote:
 From: Martin Sebor [mailto:[EMAIL PROTECTED] 

 I just found out that the /Ehc flag enables the nothrow default for C 
 linkage functions. So changing the /EHsc flag to /EHs will fix this 
 for both VC7 and 8.
 Do you happen to know if there's a #pragma that will let us 
 select the mode we need for just the one function?
 
 There's no #pragma for that, but we can compile all cpp files with
 /Ehsc, and some set of specified files with /EHs.

But, there is __declspec(throw) - right?


Re: svn commit: r565959 - /incubator/stdcxx/trunk/etc/config/src/EXTERN_C_EXCEPTIONS.cpp

2007-08-21 Thread Martin Sebor

Farid Zaripov wrote:

-Original Message-
From: Martin Sebor [mailto:[EMAIL PROTECTED] 
Sent: Saturday, August 18, 2007 12:00 AM

To: stdcxx-dev@incubator.apache.org
Subject: Re: svn commit: r565959 - 
/incubator/stdcxx/trunk/etc/config/src/EXTERN_C_EXCEPTIONS.cpp


I just found out that the /Ehc flag enables the nothrow 
default for C 
linkage functions. So changing the /EHsc flag to /EHs will fix this 
for both VC7 and 8.
Do you happen to know if there's a #pragma that will let us 
select the mode we need for just the one function?


  There's no #pragma for that, but we can compile all cpp files with
/Ehsc,
and some set of specified files with /EHs.


Okay, that's something to consider. We'll have to see how pervasive
the use of __rw_once() will be as soon as I'm done switching to it
(so far I think it'll be needed in only a handful of places) and
whether any of the initialization functions will potentially throw.

Btw., from the MSVC Exception Handling Model:
http://msdn2.microsoft.com/en-us/library/1deeycx5(VS.80).aspx
it looks like by default the compiler generates code that makes
catch blocks catch structured exceptions (in addition the C++
kind). That's generally considered bad practice, but it may be
relied on by user code for historical reasons. We need to be
careful not to impose requirements on our users that would go
against this historical practice (doing so could break working
code).

Martin


Re: svn commit: r565959 - /incubator/stdcxx/trunk/etc/config/src/EXTERN_C_EXCEPTIONS.cpp

2007-08-21 Thread Martin Sebor

William A. Rowe, Jr. wrote:

Farid Zaripov wrote:
From: Martin Sebor [mailto:[EMAIL PROTECTED] 

I just found out that the /Ehc flag enables the nothrow default for C 
linkage functions. So changing the /EHsc flag to /EHs will fix this 
for both VC7 and 8.
Do you happen to know if there's a #pragma that will let us 
select the mode we need for just the one function?

There's no #pragma for that, but we can compile all cpp files with
/Ehsc, and some set of specified files with /EHs.


But, there is __declspec(throw) - right?


There is __declspec(nothrow) to indicate that a function cannot
throw exceptions (the default for C functions) but I don't see
one to indicate the opposite, i.e., that a C function can throw.
One would think it'd be the logical extension given that all C++
functions can throw by default and no C functions can.

Here's the latest man page on __declspec(nothrow):
http://msdn2.microsoft.com/en-us/library/49147z04(VS.80).aspx

Martin


RE: svn commit: r565959 - /incubator/stdcxx/trunk/etc/config/src/EXTERN_C_EXCEPTIONS.cpp

2007-08-21 Thread Farid Zaripov
 -Original Message-
 From: Martin Sebor [mailto:[EMAIL PROTECTED] 
 Sent: Tuesday, August 21, 2007 9:36 PM
 To: stdcxx-dev@incubator.apache.org
 Subject: Re: svn commit: r565959 - 
 /incubator/stdcxx/trunk/etc/config/src/EXTERN_C_EXCEPTIONS.cpp
 
 William A. Rowe, Jr. wrote:
  Farid Zaripov wrote:
  From: Martin Sebor [mailto:[EMAIL PROTECTED]
 
  I just found out that the /Ehc flag enables the nothrow 
 default for 
  C linkage functions. So changing the /EHsc flag to /EHs will fix 
  this for both VC7 and 8.
  Do you happen to know if there's a #pragma that will let 
 us select 
  the mode we need for just the one function?
  There's no #pragma for that, but we can compile all cpp files with 
  /Ehsc, and some set of specified files with /EHs.
  
  But, there is __declspec(throw) - right?
 
 There is __declspec(nothrow) to indicate that a function 
 cannot throw exceptions (the default for C functions) but I 
 don't see one to indicate the opposite, i.e., that a C 
 function can throw.
 One would think it'd be the logical extension given that all 
 C++ functions can throw by default and no C functions can.

  You're right. But there is throw(...) exception specification
which tells the compiler that the function can throw an exception.

http://msdn2.microsoft.com/en-us/library/wfa0edys(VS.80).aspx

Farid.


Re: svn commit: r565959 - /incubator/stdcxx/trunk/etc/config/src/EXTERN_C_EXCEPTIONS.cpp

2007-08-21 Thread Martin Sebor

Farid Zaripov wrote:

-Original Message-
From: Martin Sebor [mailto:[EMAIL PROTECTED] 
Sent: Tuesday, August 21, 2007 9:26 PM

To: stdcxx-dev@incubator.apache.org
Subject: Re: svn commit: r565959 - 
/incubator/stdcxx/trunk/etc/config/src/EXTERN_C_EXCEPTIONS.cpp


  There's no #pragma for that, but we can compile all cpp 
files with 

/Ehsc, and some set of specified files with /EHs.
Okay, that's something to consider. We'll have to see how 
pervasive the use of __rw_once() will be as soon as I'm done 
switching to it (so far I think it'll be needed in only a 
handful of places) and whether any of the initialization 
functions will potentially throw.


  I've just tried to declare and define __rw_once with throw(...)
exception
specification and compiler doesn't issues warning in that case.


Good to know! We still need to decide how to handle this in
the general case (for compilers that behave like MSVC, if
there are any) but we can certainly start using this extension
to silence the MSVC warnings.




Btw., from the MSVC Exception Handling Model:
http://msdn2.microsoft.com/en-us/library/1deeycx5(VS.80).aspx
it looks like by default the compiler generates code that 
makes catch blocks catch structured exceptions (in addition 
the C++ kind). That's generally considered bad practice, but 
it may be relied on by user code for historical reasons. We 
need to be careful not to impose requirements on our users 
that would go against this historical practice (doing so 
could break working code).


  It was by default only in MSVC versions prior 7.0 (because
the only asynhronous exceptions handling model was implemented.
Since MSVC 7.0 they added synhronous exceptions handling
model and this model is used by default.


Thanks for the clarification! I've also discovered it in the
docs since I sent my mail.

Martin


RE: svn commit: r565959 - /incubator/stdcxx/trunk/etc/config/src/EXTERN_C_EXCEPTIONS.cpp

2007-08-21 Thread Travis Vitek

 

Martin Sebor wrote:

Farid Zaripov wrote:

 
 I've just tried to declare and define __rw_once with throw(...)
 exception specification and compiler doesn't issues warning in
 that case.


Yes, but the documentation linked to explicitly says...

  Explicit exception specifications are not allowed on C functions.
  [http://msdn2.microsoft.com/en-us/library/wfa0edys(VS.80).aspx]

I tested, it does compile, and the destructors are getting called as
they should when an explicit throw(...) spec is added to the C linkage
function. That said, I cringe at the thought relying on behavior that is
documented to not work or is not supported.

Maybe when the documentation is referring to C functions it means
functions that are compiled as C source [x.c instead of x.cpp] and not
functions with C linkage?


Good to know! We still need to decide how to handle this in
the general case (for compilers that behave like MSVC, if
there are any) but we can certainly start using this extension
to silence the MSVC warnings.


Is the goal really to just squelch the warnings? I hope not.

So back at square one, I have another question. Lets assume a program
will abort() if an exception is thrown through a C function. This
characterization test will fail, and the build framework will probably
set a preprocessor flag _RWSTD_NO_EXTERN_C_EXCEPTIONS. What exactly
would we do to prevent this from being a problem? I can think of two
things.

  1. Add a try/catch block inside every once function definition
 that might throw.
  2. Implement our own pthread_once() type function that has C++
 linkage and use it with all configurations on all platforms.

Both solutions are compatible with all systems, and would eliminate the
warning on MSVC as a side effect. Obviously the first option isn't that
pleasant because there is no _good_ way I can see to communicate a
failure back to the application. Is there something wrong with the
second option?

Travis


Re: svn commit: r565959 - /incubator/stdcxx/trunk/etc/config/src/EXTERN_C_EXCEPTIONS.cpp

2007-08-21 Thread Martin Sebor

Travis Vitek wrote:
 


Martin Sebor wrote:

Farid Zaripov wrote:


I've just tried to declare and define __rw_once with throw(...)
exception specification and compiler doesn't issues warning in
that case.


Yes, but the documentation linked to explicitly says...

  Explicit exception specifications are not allowed on C functions.
  [http://msdn2.microsoft.com/en-us/library/wfa0edys(VS.80).aspx]


Yet they describe the behavior of functions, including those
with C linkage, in terms of explicit exception specification.
How ironic!



I tested, it does compile, and the destructors are getting called as
they should when an explicit throw(...) spec is added to the C linkage
function. That said, I cringe at the thought relying on behavior that is
documented to not work or is not supported.


No kidding!



Maybe when the documentation is referring to C functions it means
functions that are compiled as C source [x.c instead of x.cpp] and not
functions with C linkage?


Who knows... Have you tried it?




Good to know! We still need to decide how to handle this in
the general case (for compilers that behave like MSVC, if
there are any) but we can certainly start using this extension
to silence the MSVC warnings.



Is the goal really to just squelch the warnings? I hope not.


No, not just that (we could simply use #pragma warning to silence
them if that was the only goal).



So back at square one, I have another question. Lets assume a program
will abort() if an exception is thrown through a C function. This
characterization test will fail, and the build framework will probably
set a preprocessor flag _RWSTD_NO_EXTERN_C_EXCEPTIONS. What exactly
would we do to prevent this from being a problem? I can think of two
things.

  1. Add a try/catch block inside every once function definition
 that might throw.
  2. Implement our own pthread_once() type function that has C++
 linkage and use it with all configurations on all platforms.

Both solutions are compatible with all systems, and would eliminate the
warning on MSVC as a side effect. Obviously the first option isn't that
pleasant because there is no _good_ way I can see to communicate a
failure back to the application. Is there something wrong with the
second option?


Good questions.

I suppose the potential overhead would be my biggest concern.
The solution we discussed recently on another list (overloading
pthread_once() for extern C++ functions) involves dynamically
allocating a small chunk of memory. That's a steep price to pay
for one time initialization.

But we might be solving a non-issue. I'm not sure yet that there
are any one-time initializers in the library that can throw an
exception. So I think we're safe until we've actually found one
that does. Although it surely would be nice to have a robust
solution in place just in case we add an initializer that can
throw in the future.

Btw., there is another alternative: For compilers like MSVC
that ignore the difference between extern C and extern C++
functions (i.e., where _RWSTD_NO_EXTERN_C_COMPATIBILITY is
#undefined) we can just pass extern C++ functions to
__rw_once().

Martin


RE: svn commit: r565959 - /incubator/stdcxx/trunk/etc/config/src/EXTERN_C_EXCEPTIONS.cpp

2007-08-21 Thread Travis Vitek
 

Martin Sebor wrote:
 
 Maybe when the documentation is referring to C functions it means
 functions that are compiled as C source [x.c instead of 
 x.cpp] and not functions with C linkage?

Who knows... Have you tried it?

I have now. The compiler chokes on 'throw' when compiling C sources as
it should.

 

Good questions.

I suppose the potential overhead would be my biggest concern.
The solution we discussed recently on another list (overloading
pthread_once() for extern C++ functions) involves dynamically
allocating a small chunk of memory. That's a steep price to pay
for one time initialization.


Well we wouldn't need to do that as the entire system would be
implemented in C++. You already provide such an implementation for the
windows configuration.


But we might be solving a non-issue. I'm not sure yet that there
are any one-time initializers in the library that can throw an
exception. So I think we're safe until we've actually found one
that does. Although it surely would be nice to have a robust
solution in place just in case we add an initializer that can
throw in the future.


Agreed, and agreed.



Re: svn commit: r565959 - /incubator/stdcxx/trunk/etc/config/src/EXTERN_C_EXCEPTIONS.cpp

2007-08-21 Thread Martin Sebor

Travis Vitek wrote:
 


Martin Sebor wrote:

Maybe when the documentation is referring to C functions it means
functions that are compiled as C source [x.c instead of 
x.cpp] and not functions with C linkage?

Who knows... Have you tried it?


I have now. The compiler chokes on 'throw' when compiling C sources as
it should.


Makes sense.

So I wonder what the heck the purpose of throw(...) is supposed
to be given that every C++ function is always (regardless of any
compiler switches) implicitly declared with it and if it's not
allowed on C functions (clearly it *is* allowed if the compiler
accepts it, so what gives?)

Martin


RE: svn commit: r565959 - /incubator/stdcxx/trunk/etc/config/src/EXTERN_C_EXCEPTIONS.cpp

2007-08-17 Thread Travis Vitek
 

Martin Sebor wrote: 

Travis Vitek wrote:
 Martin,
 
 I'm not sure if you're aware, but I don't believe that the 
 destructors for stack objects inside the C functions will
 be called. I know that this is the case for MSVC7/8. This
 isn't an issue for your testcase, but it may be an issue
 for the functions invoked by __rw_once.

Interesting! I didn't know about this limitation. It's something
we need to keep in mind when writing the initialization functions.
Perhaps the solution will be to require the initialization function
to have the empty exception specification. That way we could rely
on the compiler to detect initialization functions that can throw.


I just found out that the /Ehc flag enables the nothrow default
for C linkage functions. So changing the /EHsc flag to /EHs will
fix this for both VC7 and 8.

Travis


Re: svn commit: r565959 - /incubator/stdcxx/trunk/etc/config/src/EXTERN_C_EXCEPTIONS.cpp

2007-08-17 Thread Martin Sebor

Travis Vitek wrote:
 

Martin Sebor wrote: 


Travis Vitek wrote:

Martin,

I'm not sure if you're aware, but I don't believe that the 
destructors for stack objects inside the C functions will

be called. I know that this is the case for MSVC7/8. This
isn't an issue for your testcase, but it may be an issue
for the functions invoked by __rw_once.

Interesting! I didn't know about this limitation. It's something
we need to keep in mind when writing the initialization functions.
Perhaps the solution will be to require the initialization function
to have the empty exception specification. That way we could rely
on the compiler to detect initialization functions that can throw.



I just found out that the /Ehc flag enables the nothrow default
for C linkage functions. So changing the /EHsc flag to /EHs will
fix this for both VC7 and 8.


Do you happen to know if there's a #pragma that will let us select
the mode we need for just the one function?

Martin


RE: svn commit: r565959 - /incubator/stdcxx/trunk/etc/config/src/EXTERN_C_EXCEPTIONS.cpp

2007-08-14 Thread Travis Vitek

Martin,

I'm not sure if you're aware, but I don't believe that the destructors
for stack objects inside the C functions will be called. I know that
this is the case for MSVC7/8. This isn't an issue for your testcase, but
it may be an issue for the functions invoked by __rw_once.

I think this is by design, but I found it a little weird that the ascii
value of the first character of each parameter is passed to
div_throw/div_nothrow. I had the urge to add modify the argument
processing lines to something more like this so that I could pass
arguments and get the expected results.

const int x = argc  2 ? 0 : int (*argv [1]) - '0';
const int y = argc  3 ? 0 : int (*argv [2]) - '0';

Travis


Author: sebor
Date: Tue Aug 14 15:48:02 2007
New Revision: 565959

URL: http://svn.apache.org/viewvc?view=revrev=565959
Log:
2007-08-14  Martin Sebor  [EMAIL PROTECTED]

   * EXTERN_C_EXCEPTIONS.cpp: New config test to determine whether
   it's possible to throw exceptions from functions with C language
   linkage.

Added:

incubator/stdcxx/trunk/etc/config/src/EXTERN_C_EXCEPTIONS.cpp  
 (with props)

Added: incubator/stdcxx/trunk/etc/config/src/EXTERN_C_EXCEPTIONS.cpp
URL: 
http://svn.apache.org/viewvc/incubator/stdcxx/trunk/etc/config/src/EXTE
RN_C_EXCEPTIONS.cpp?view=autorev=565959


RE: svn commit: r565959 - /incubator/stdcxx/trunk/etc/config/src/EXTERN_C_EXCEPTIONS.cpp

2007-08-14 Thread Travis Vitek

Sorry, I should clarify that. Destructors for stack objects in C
functions aren't called when an exception is thrown. Testcase...

C:\(type t.cpp)  (cl /nologo /EHsc t.cpp)
struct Object
{
static int counter;
Object() {
Object::counter += 1;
}
~Object() {
Object::counter -= 1;
}
};

/* static */
int Object::counter = 0;

extern C {

int extern_c_function (int x, int y, int (*fun)(int, int))
{
Object obj;

if (fun)
return fun (x, y);

return 0;
}

int div_throw (int x, int y)
{
Object obj;

if (0 == y)
throw y;

return x / y;
}

}   // extern C


int main (int argc, char *argv[])
{
const int x = argc  2 ? 0 : int (*argv [1]) - '0';
const int y = argc  3 ? 0 : int (*argv [2]) - '0';

try {
extern_c_function (x, y, div_throw);
}
catch (int res) {
// nothing
}

return Object::counter != 0;
}
t.cpp
t.cpp(32) : warning C4297: 'div_throw' : function assumed not to throw
an exception but does
The function is extern C and /EHc was specified

C:\t 1 1

C:\if errorlevel 1 (echo failure) else (echo success!)
success!

C:\t 1 0

C:\if errorlevel 1 (echo failure!) else (echo success!)
failure!

-Original Message-
From: Travis Vitek [mailto:[EMAIL PROTECTED] 
Sent: Tuesday, August 14, 2007 5:18 PM
To: stdcxx-dev@incubator.apache.org
Subject: RE: svn commit: r565959 - 
/incubator/stdcxx/trunk/etc/config/src/EXTERN_C_EXCEPTIONS.cpp


Martin,

I'm not sure if you're aware, but I don't believe that the destructors
for stack objects inside the C functions will be called. I know that
this is the case for MSVC7/8. This isn't an issue for your 
testcase, but
it may be an issue for the functions invoked by __rw_once.

I think this is by design, but I found it a little weird that the ascii
value of the first character of each parameter is passed to
div_throw/div_nothrow. I had the urge to add modify the argument
processing lines to something more like this so that I could pass
arguments and get the expected results.

const int x = argc  2 ? 0 : int (*argv [1]) - '0';
const int y = argc  3 ? 0 : int (*argv [2]) - '0';

Travis




Re: svn commit: r565959 - /incubator/stdcxx/trunk/etc/config/src/EXTERN_C_EXCEPTIONS.cpp

2007-08-14 Thread Martin Sebor

Travis Vitek wrote:

Martin,

I'm not sure if you're aware, but I don't believe that the destructors
for stack objects inside the C functions will be called. I know that
this is the case for MSVC7/8. This isn't an issue for your testcase, but
it may be an issue for the functions invoked by __rw_once.


Interesting! I didn't know about this limitation. It's something
we need to keep in mind when writing the initialization functions.
Perhaps the solution will be to require the initialization function
to have the empty exception specification. That way we could rely
on the compiler to detect initialization functions that can throw.



I think this is by design, but I found it a little weird that the ascii
value of the first character of each parameter is passed to
div_throw/div_nothrow. I had the urge to add modify the argument
processing lines to something more like this so that I could pass
arguments and get the expected results.


Yeah, it doesn't make much sense. The only reason for the code
is to try to prevent overachieving optimizers from generating
C++ code for the C functions and doing the right thing in
the simple test case. I should add a comment explaining this.

Martin



const int x = argc  2 ? 0 : int (*argv [1]) - '0';
const int y = argc  3 ? 0 : int (*argv [2]) - '0';

Travis


Author: sebor
Date: Tue Aug 14 15:48:02 2007
New Revision: 565959

URL: http://svn.apache.org/viewvc?view=revrev=565959
Log:
2007-08-14  Martin Sebor  [EMAIL PROTECTED]

* EXTERN_C_EXCEPTIONS.cpp: New config test to determine whether
it's possible to throw exceptions from functions with C language
linkage.

Added:
   
incubator/stdcxx/trunk/etc/config/src/EXTERN_C_EXCEPTIONS.cpp  
(with props)


Added: incubator/stdcxx/trunk/etc/config/src/EXTERN_C_EXCEPTIONS.cpp
URL: 
http://svn.apache.org/viewvc/incubator/stdcxx/trunk/etc/config/src/EXTE

RN_C_EXCEPTIONS.cpp?view=autorev=565959