[Bug libstdc++/25191] exception_defines.h #defines try/catch

2008-11-20 Thread hhinnant at apple dot com


--- Comment #66 from hhinnant at apple dot com  2008-11-20 17:40 ---
(In reply to comment #65)
 Subject: Re:  exception_defines.h #defines try/catch
 
 No, it doesn't make any sense to use try/catch in a program that you're 
 planning to build with -fno-exceptions.  It does, however, make sense to 
 use try/catch in a general purpose library that you want to work with 
 exceptions enabled or disabled, such as libstdc++.
 
 I believe Lubos is arguing that such libraries ought to use preprocessor 
 tricks to accomplish this, but defining something like __try and __catch 
 instead of try and catch.  The difference between this approach and my 
 patch is that it requires the library writer to jump through hoops to 
 make their code work with exceptions enabled and disabled.  I guess 
 Lubos thinks this is good, that this is an unusual thing to want to do 
 and so people that want to do it need to be very explicit about it so 
 that people who don't want that but mistakenly build their code with 
 -fno-exceptions get an error rather than a warning.
 
 Anyone else have an opinion about this?
 
 And yes, -Wexceptions is on by default in my patch.

I've tried really hard to just stay out of this one. :-)  I think Jason makes a
good argument.  However I just surveyed a bunch of my own code written to work
both with and without exceptions enabled, using macro hoops.  In about 95% of
the cases transforming:

try
{
   X
} 
catch (Y)
{
   Z
}

to just:

X

is exactly what I want.  In the other 5% of the cases it is not.  In these
(relatively rare, but not uncommon) cases, the code under X gets transformed
into code that checks return values for error codes and acts on that error
code:

int er = X
if (er)
   return P

This scenario usually pops up when X is doing an allocation which throws when
exceptions are enabled and returns null when exceptions are disabled.

All that being said, is Jason's patch good or bad?  shrug  I'm still going to
have to manually design 100% of my try/catch clauses for exceptions enabled and
disabled.  If I don't, then I'll have a 5% bug rate even with Jason's patch. 
Part of me would prefer the error just to ensure that I haven't forgotten to
design for the exceptions-disabled case, even if that design would simply
translate to X.  Perhaps the warning will fill that role, I do not know.


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=25191



[Bug libstdc++/25191] exception_defines.h #defines try/catch

2007-04-27 Thread hhinnant at apple dot com


--- Comment #37 from hhinnant at apple dot com  2007-04-27 14:15 ---
Thanks for looking at this issue.

Also consider Andrew's point about useful diagnostics, for example from comment
#4.  And the followup to that point in #33 which includes field experience on
how other compilers deal with this same option.  I.e. from this viewpoint,
getting a compile time error when you use try/catch with -fnoexceptions is a
feature, not a bug.


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=25191



[Bug other/28145] C++ (throw() and catch(...) {/* fall through */ } ) and pthread cancellation are incompatible (at least with NPTL)

2007-04-15 Thread hhinnant at apple dot com


--- Comment #16 from hhinnant at apple dot com  2007-04-15 16:13 ---
(In reply to comment #15)

This makes clean up / rethrow during cancellation awkward.  Code would have to
check for two (or more) different kinds of cancellation:  Am I executing in an
OS thread, or in a thread pool?


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=28145



[Bug c++/29939] Add rvalue references (C++0x)

2007-02-21 Thread hhinnant at apple dot com


--- Comment #5 from hhinnant at apple dot com  2007-02-21 20:17 ---
Russell Yanofsky has submitted a patch implementing N2118:

http://gcc.gnu.org/ml/gcc-patches/2007-02/msg01760.html


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=29939



[Bug libstdc++/17012] [DR 526] std::list's function, remove, looks like it is reading memory that has been freed.

2007-02-07 Thread hhinnant at apple dot com


--- Comment #12 from hhinnant at apple dot com  2007-02-07 16:46 ---
At the ad-hoc LWG meeting in Batavia, Jan 22-24, 2007, the LWG decided that
self referencing code in list::remove must work.  Here is a preview of the
issue which is currently set to become official at the Spring '07 meeting:

http://home.twcny.rr.com/hinnant/cpp_extensions/issues_preview/lwg-active.html#526

Here is a patch to mainline to make it work.  I believe the approach taken by
this patch is superior to copying the value as it currently looks like a future
standard will not require that the value_type be copyable.  Additionally the
cost of copying the value_type can be arbitrarily large.

If we have a utility similar to boost::address_of, that might be better than
using operator to get the address of the value_type (to accommodate types
which overload operator).

Index: libstdc++-v3/include/bits/list.tcc
===
--- libstdc++-v3/include/bits/list.tcc  (revision 121691)
+++ libstdc++-v3/include/bits/list.tcc  (working copy)
@@ -176,14 +176,22 @@
 {
   iterator __first = begin();
   iterator __last = end();
+  iterator __extra = __last;
   while (__first != __last)
{
  iterator __next = __first;
  ++__next;
  if (*__first == __value)
-   _M_erase(__first);
+ {
+   if (__value != *__first)
+ _M_erase(__first);
+   else
+ __extra = __first;
+ }
  __first = __next;
}
+  if (__extra != __last)
+_M_erase(__extra);
 }

   templatetypename _Tp, typename _Alloc


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=17012



[Bug libstdc++/17012] [DR 526] std::list's function, remove, looks like it is reading memory that has been freed.

2007-02-07 Thread hhinnant at apple dot com


--- Comment #13 from hhinnant at apple dot com  2007-02-07 16:59 ---
(In reply to comment #12)

 If we have a utility similar to boost::address_of, that might be better than
 using operator to get the address of the value_type (to accommodate types
 which overload operator).

Oops, I forgot about allocator::address and:

http://home.twcny.rr.com/hinnant/cpp_extensions/issues_preview/lwg-active.html#580

New patch uses allocator::address:

Index: libstdc++-v3/include/bits/list.tcc
===
--- libstdc++-v3/include/bits/list.tcc  (revision 121691)
+++ libstdc++-v3/include/bits/list.tcc  (working copy)
@@ -176,14 +176,23 @@
 {
   iterator __first = begin();
   iterator __last = end();
+  iterator __extra = __last;
+  allocator_type __a = get_allocator();
   while (__first != __last)
{
  iterator __next = __first;
  ++__next;
  if (*__first == __value)
-   _M_erase(__first);
+ {
+   if (__a.address(__value) != __a.address(*__first))
+ _M_erase(__first);
+   else
+ __extra = __first;
+ }
  __first = __next;
}
+  if (__extra != __last)
+_M_erase(__extra);
 }

   templatetypename _Tp, typename _Alloc


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=17012



[Bug libstdc++/17012] [DR 526] std::list's function, remove, looks like it is reading memory that has been freed.

2007-02-07 Thread hhinnant at apple dot com


--- Comment #15 from hhinnant at apple dot com  2007-02-07 17:22 ---
(In reply to comment #14)
 Unless __value comes from the list, does the standard require
 __a.address(__value) to work?
 

That's a good question Chris.  The way I read the current draft, I believe the
answer is no.  This looks like another defect report to me.  In the definition
of r and s in [allocator.requirements] I see no reason to have the clause
obtained by the expression *p.  But I'll open a DR (635) and let the LWG
decide.


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=17012



[Bug c++/29939] Add rvalue references (C++0x)

2006-11-29 Thread hhinnant at apple dot com


--- Comment #3 from hhinnant at apple dot com  2006-11-29 18:36 ---
Recent work:

http://mndfck.org/~pedro.lamarao/projects/c++0x/
http://home.twcny.rr.com/hinnant/cpp_extensions/rvalue_ref_test/


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=29939



[Bug c++/29939] Please implement rvalue references

2006-11-22 Thread hhinnant at apple dot com


--- Comment #2 from hhinnant at apple dot com  2006-11-22 16:21 ---
If there is a plan, I don't know about it.

Russell Yanofsky has a prototype implementation here:

http://russ.yanofsky.org/rref/

I haven't looked at it enough to know how complete it is.  It was done a couple
of years ago.


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=29939



[Bug other/28145] C++ (throw() and catch(...) {/* fall through */ } ) and pthread cancellation are incompatible (at least with NPTL)

2006-11-01 Thread hhinnant at apple dot com


--- Comment #14 from hhinnant at apple dot com  2006-11-01 23:33 ---
So swallowing a cancel-exception (in C++) is sometimes the right thing to do.

Imagine a thread pool executing a queue of tasks.  These tasks can well have
handles so that clients can wait/join with results in the future.  Such results
could be normal or exceptional.  If you've got a hung task in a thread pool,
maybe you want to cancel it.  That means the task should end, but once the OS
thread dumps the task, records the exception that ended it (cancellation), the
thread should be free to get the next task out of the queue and execute it.


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=28145



[Bug libstdc++/29224] New: -Wshadow causing warning in tr1/functional

2006-09-25 Thread hhinnant at apple dot com
The following test.cpp:

#include tr1/functional

struct A
{
void foo() {}
};

int main()
{
std::tr1::mem_fn(A::foo);
}

compiled with:

g++ -Wshadow test.cpp

causes:

/usr/include/c++/4.0.0/tr1/functional_iterate.h: In constructor
'std::tr1::_Mem_fn_Res (_Class::*)()::_Mem_fn(_Res (_Class::*)()) [with _Res
= void, _Class = A]':
/usr/include/c++/4.0.0/tr1/functional:502:   instantiated from
'std::tr1::_Mem_fn_Res _Class::* std::tr1::mem_fn(_Tp _Class::*) [with _Tp =
void ()(), _Class = A]'
test.cpp:10:   instantiated from here
/usr/include/c++/4.0.0/tr1/functional_iterate.h:202: warning: declaration of
'__pmf' shadows a member of 'this'

The following patch will silence the warning:

$ svn diff
Index: libstdc++-v3/include/tr1/functional_iterate.h
===
--- libstdc++-v3/include/tr1/functional_iterate.h   (revision 117204)
+++ libstdc++-v3/include/tr1/functional_iterate.h   (working copy)
@@ -195,7 +195,7 @@
   public:
 typedef _Res result_type;

-explicit _Mem_fn(_Functor __pmf) : __pmf(__pmf) { }
+explicit _Mem_fn(_Functor __pf) : __pmf(__pf) { }

 // Handle objects
 _Res
@@ -249,7 +249,7 @@
   public:
 typedef _Res result_type;

-explicit _Mem_fn(_Functor __pmf) : __pmf(__pmf) { }
+explicit _Mem_fn(_Functor __pf) : __pmf(__pf) { }

 // Handle objects
 _Res
@@ -303,7 +303,7 @@
   public:
 typedef _Res result_type;

-explicit _Mem_fn(_Functor __pmf) : __pmf(__pmf) { }
+explicit _Mem_fn(_Functor __pf) : __pmf(__pf) { }

 // Handle objects
 _Res
@@ -357,7 +357,7 @@
   public:
 typedef _Res result_type;

-explicit _Mem_fn(_Functor __pmf) : __pmf(__pmf) { }
+explicit _Mem_fn(_Functor __pf) : __pmf(__pf) { }

 // Handle objects
 _Res


-- 
   Summary: -Wshadow causing warning in tr1/functional
   Product: gcc
   Version: 4.0.1
Status: UNCONFIRMED
  Severity: minor
  Priority: P3
 Component: libstdc++
AssignedTo: unassigned at gcc dot gnu dot org
ReportedBy: hhinnant at apple dot com


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=29224



[Bug c++/28308] New: Language linkage not part of function type

2006-07-07 Thread hhinnant at apple dot com
From the C++ standard, 7.5p1:

Two function types with different language linkages are distinct types even if
they are otherwise identical.

The following code tests for this and should compile (a successful compile
indicates a test pass).

template bool
struct static_assert;

template
struct static_asserttrue {};

extern C
{
char myexit(void (*)(void));
typedef void (*CF)(void);
}

int myexit(void (*f)())
{
static_assertsizeof(myexit((CF)f)) == 1 e1;
return myexit((CF)f);
}

int main()
{
}

extern C
{
char myexit(void (*)(void))
{
return 0;
}
}


-- 
   Summary: Language linkage not part of function type
   Product: gcc
   Version: 4.0.1
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
AssignedTo: unassigned at gcc dot gnu dot org
ReportedBy: hhinnant at apple dot com
  GCC host triplet: Darwin ppc


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=28308



[Bug c++/28017] lack of guard variables for explicitly instantiated template static data

2006-06-19 Thread hhinnant at apple dot com


--- Comment #10 from hhinnant at apple dot com  2006-06-19 18:11 ---
It turns out this still isn't quite right.  Looks like we need:

#define NEEDS_GUARD_P(decl) (TREE_PUBLIC (decl)  (DECL_COMMON (decl) \
|| DECL_ONE_ONLY (decl) \
|| DECL_WEAK (decl) \
||
(TARGET_WEAK_NOT_IN_ARCHIVE_TOC \
DECL_LANG_SPECIFIC
(decl) \
   
(DECL_EXPLICIT_INSTANTIATION (decl) \
   || 
DECL_TEMPLATE_SPECIALIZATION (decl)

The former solution was dereferencing a null pointer.


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=28017



[Bug c++/28017] New: lack of guard variables for explicitly instantiated template static data

2006-06-13 Thread hhinnant at apple dot com
I was passed a test case consisting of two translation units:

// test.h

#include iostream

class A
{
public:

A()
{
mString = new char[2];
std::cout  new: mString has value   (void*) mString  std::endl;
}

~A()
{
std::cout  delete: mString has value   (void*) mString 
std::endl;
delete [] mString;
}

void f()
{
}

private:

char* mString;
};


templatetypename T
class Test
{
public:

Test()
{
sA.f();
}

private:
static A sA;
};

templatetypename T
A TestT::sA;

// test.cpp

#include test.h

template class Testint;

int foo()
{
return 0;
}

// main.cpp

#include test.h

int foo();

int main()
{
Testint theTest;
foo();
return 0;
}

When compiled with something like:

g++ -o test test.cpp main.cpp

the test shows evidence of the static Testint::sA being
constructed/destructed twice:

new: mString has value 0x5002d0
new: mString has value 0x500300
delete: mString has value 0x500300
delete: mString has value 0x500300

The desired output should be more like:

new: mString has value 0x5002d0
delete: mString has value 0x5002d0

Further inspection reveals that the guard variable for this static is not being
generated in test.cpp because of the explicit instantiation there (tested on
Apple's gcc 4.0.1).

I am wondering if an appropriate fix might be in:

gcc/cp/decl2.c, in function start_static_initialization_or_destruction

Change the if statement that looks like:

  if (TREE_PUBLIC (decl)  (DECL_COMMON (decl)
 || DECL_ONE_ONLY (decl)
 || DECL_WEAK (decl)))
{
  tree guard_cond;

to:

  if (TREE_PUBLIC (decl)  (DECL_COMMON (decl)
 || DECL_ONE_ONLY (decl)
 || DECL_WEAK (decl)
 || DECL_EXPLICIT_INSTANTIATION (decl)))
{
  tree guard_cond;

I looked in the mainline decl2.c and found the same logic in the macro
NEEDS_GUARD_P.  Here I'm suggesting changing:

#define NEEDS_GUARD_P(decl) (TREE_PUBLIC (decl)  (DECL_COMMON (decl)  \
|| DECL_ONE_ONLY (decl) \
|| DECL_WEAK (decl)))

to:

#define NEEDS_GUARD_P(decl) (TREE_PUBLIC (decl)  (DECL_COMMON (decl)  \
|| DECL_ONE_ONLY (decl) \
|| DECL_WEAK (decl) \
||
DECL_EXPLICIT_INSTANTIATION (decl)))


-- 
   Summary: lack of guard variables for explicitly instantiated
template static data
   Product: gcc
   Version: 4.0.1
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
AssignedTo: unassigned at gcc dot gnu dot org
ReportedBy: hhinnant at apple dot com
  GCC host triplet: darwin ppc


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=28017



[Bug c++/28017] lack of guard variables for explicitly instantiated template static data

2006-06-13 Thread hhinnant at apple dot com


--- Comment #5 from hhinnant at apple dot com  2006-06-13 21:23 ---
(In reply to comment #4)
For Darwin we do not want explicit instantiations to be
linkonce.  */
 
 
 This is why this testcase fails on darwin.
 We should instead of just adding DECL_EXPLICIT_INSTANTIATION, check
 TARGET_WEAK_NOT_IN_ARCHIVE_TOC.
 
 (!TARGET_WEAK_NOT_IN_ARCHIVE_TOC
   || (! DECL_EXPLICIT_INSTANTIATION (decl)
! DECL_TEMPLATE_SPECIALIZATION (decl)))
 
 This is a darwin only issue.

I'm having trouble deciding exactly what you mean.  Is this what you mean:

#define NEEDS_GUARD_P(decl) (!TARGET_WEAK_NOT_IN_ARCHIVE_TOC \
  || (! DECL_EXPLICIT_INSTANTIATION (decl) \
   ! DECL_TEMPLATE_SPECIALIZATION (decl)))

Or do you mean:

#define NEEDS_GUARD_P(decl) (TREE_PUBLIC (decl)  (DECL_COMMON (decl)  \
|| DECL_ONE_ONLY (decl) \
|| DECL_WEAK (decl) \
||
(!TARGET_WEAK_NOT_IN_ARCHIVE_TOC \
  || (! DECL_EXPLICIT_INSTANTIATION (decl) \
   ! DECL_TEMPLATE_SPECIALIZATION (decl)

?


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=28017



[Bug c++/28017] lack of guard variables for explicitly instantiated template static data

2006-06-13 Thread hhinnant at apple dot com


--- Comment #7 from hhinnant at apple dot com  2006-06-13 21:41 ---
(In reply to comment #6)
 Subject: Re:  lack of guard variables for explicitly instantiated template
 static data
 
  #define NEEDS_GUARD_P(decl) (TREE_PUBLIC (decl)  (DECL_COMMON (decl)  
  \
  || DECL_ONE_ONLY (decl) 
  \
  || DECL_WEAK (decl) \
  ||
  (!TARGET_WEAK_NOT_IN_ARCHIVE_TOC \
|| (! DECL_EXPLICIT_INSTANTIATION (decl) \
 ! DECL_TEMPLATE_SPECIALIZATION (decl)
  
  ?
 
 The latter.

Thanks.  But this doesn't pass the test case on darwin.  I'm not familiar
enough with the C++ FE to understand TARGET_WEAK_NOT_IN_ARCHIVE_TOC.  Could you
double check the above.  The ! in front of DECL_EXPLICIT_INSTANTIATION looks
especially suspicious to me.


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=28017



[Bug c++/28017] lack of guard variables for explicitly instantiated template static data

2006-06-13 Thread hhinnant at apple dot com


--- Comment #9 from hhinnant at apple dot com  2006-06-13 22:02 ---
(In reply to comment #8)

Thanks.  That not only makes sense to me now, but it passes the test. :-)


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=28017



[Bug libstdc++/27168] New: __basic_filechar::xsgetn does not deal well with pipes

2006-04-14 Thread hhinnant at apple dot com
Test case:

#include cstdlib
#include iostream
#include unistd.h
#include string.h

int
main(int argc, char * argv[])
{
  if (argc != 2)
{
  std::cerr  Usage: ./test writer | ./test reader  std::endl;
  return 2;
}

  if (strcmp(reader, argv[1]) == 0)
{
  // note, no input/output is allowed to happen before this call.
  std::cin.sync_with_stdio(false);
  int length = 0;
  while (std::cin.good())
{
  char buffer[BUFSIZ];
  (void)std::cin.read(buffer, sizeof(buffer));
  length += std::cin.gcount();
}

  if (length == 82)
{
  std::cerr  Success  std::endl;
  return EXIT_SUCCESS;
}
  else
{
  std::cerr  Failure, length is   length  std::endl;
  return EXIT_FAILURE;
  }
}
  else if (strcmp(writer, argv[1]) == 0)
{
  std::cout  1234567890123456789012345678901234567890  std::endl;
  sleep(1);
  std::cout  1234567890123456789012345678901234567890  std::endl;
  return EXIT_SUCCESS;
}
  else
{
  std::cerr  Bad argument  std::endl;
  return 3;
}
}

Analysis:

When sync_with_stdio(false), cin uses basic_filebuf which is based on
__basic_file, and its xsgetn function:

  streamsize 
  __basic_filechar::xsgetn(char* __s, streamsize __n)
  {
streamsize __ret;
do
  __ret = read(this-fd(), __s, __n);
while (__ret == -1L  errno == EINTR);
return __ret;
  }

When fd() refers to a pipe, this function may return before __n characters are
read, but also before an end-of-file is detected (say if the pipe supplier just
isn't finished yet).  For the Posix read function this is a normal operating
mode.  However for one client of this function (basic_filebuf::xsgetn, called
by istream::read), if less than __n characters are returned, this represents an
error, subsequently setting failbit|eofbit in the istream.

The fix is to change  __basic_filechar::xsgetn to hang in there until either
EOF is detected, or until there is a non-recoverable error.  I believe the
following rewrite will do the job:

  streamsize 
  __basic_filechar::xsgetn(char* __s, streamsize __n)
  {
streamsize __ret = 0;
for (streamsize __i; __n  0; __ret += __i, __s += __i, __n -= __i)
{
   __i = read(this-fd(), __s, __n);
   if (__i == 0)
 break;
   if (__i == -1)
   {
 if (!(errno == EINTR || errno == EAGAIN))
   break;
 __i = 0;
   }
}
return __ret;
  }


-- 
   Summary: __basic_filechar::xsgetn does not deal well with pipes
   Product: gcc
   Version: 4.0.1
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: libstdc++
AssignedTo: unassigned at gcc dot gnu dot org
ReportedBy: hhinnant at apple dot com
  GCC host triplet: Mac OS 10.4.5


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=27168



[Bug c++/25979] New: incorrect codegen for conditional

2006-01-26 Thread hhinnant at apple dot com
I'm not positive whether or not this is a duplicate of 25895.  I figured I'd
better enter it just in case it wasn't.  Test case:

#include stdio.h

struct A
{
A() : data1_(0), data2_(0) {}
A(int i, int j) : data1_(i), data2_(j) {}
A operator+(int);
friend A operator+(int, const A);
~A() {}
//private:
int data1_;
int data2_;
};

extern bool x;

void display(const A x)
{
printf(%d %d\n, x.data1_, x.data2_);
}

int main()
{
A a1(1,2);
a1 = (x ? a1 + 3 : 3 + a1);
display(a1);
}

bool x = false;

A
A::operator+(int i)
{
A a;
a = *this;
a.data2_ = i;
return a;
}

A
operator+(int i, const A x)
{
A a;
a = x;
a.data1_ = i;
return a;
}

Output:

3 0

Expected output:

3 2

The gimple tree (-fdump-tree-gimple) is showing statements like:

  operator+ (a1, 3, a1) [return slot addr];

which shoud instead be:

 operator+ (temp, 3, a1) [return slot addr];
 ...
 a1 = temp;

The bad codegen is sensitive to the presence or absence of special member
functions.  For example if you comment out ~A(), you get the expected output.


-- 
   Summary: incorrect codegen for conditional
   Product: gcc
   Version: 4.0.1
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
AssignedTo: unassigned at gcc dot gnu dot org
ReportedBy: hhinnant at apple dot com


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=25979



[Bug c++/25950] New: Reference binding and explicit copy constructors

2006-01-24 Thread hhinnant at apple dot com
Consider:

   struct X {
  X();
  explicit X(const X);
   };

void f(X);
void g(const X);

int main()
{
X x;
f(x);
f(X());
g(x);
g(X());
}

We currently give errors for f(x), f(X()) and g(X()), but not g(x).  This is
not quite the behavior of EDG which allows g(X()).

There are (at least) two pertinent cwg defect reports:  152 and 391.  152 has
TC1 status (it is normative) and clarifies the behavior for f(), and is
consistent with the bevavior of both gcc and EDG.  Issue 391 addresses g() and
(I believe) explains the discrepancy between gcc and EDG by specifying that X()
will bind directly to the reference parameter of g() with no copy.

This issue has been voted on in full committee and approved as a dr.  However
the next available time to make anything normative is C++0X.  So 391 has been
applied to the working draft, and EDG has apparently implemented it.

I respectfully request that gcc implement it as well.  The issue is
non-controversial on the committee and is causing problems with client code
today.


-- 
   Summary: Reference binding and explicit copy constructors
   Product: gcc
   Version: 4.0.1
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
AssignedTo: unassigned at gcc dot gnu dot org
ReportedBy: hhinnant at apple dot com


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=25950



[Bug c++/25950] [3.4/4.0/4.1 Regression] [DR 391] Reference binding and explicit copy constructors

2006-01-24 Thread hhinnant at apple dot com


--- Comment #3 from hhinnant at apple dot com  2006-01-24 22:51 ---
More information:

I now believe I unknowingly misled when I surmized that EDG had implemented cwg
391.  If you declare the copy ctor private in the example, EDG rejects g(X())
based on accessibility.  Rather I am now surmizing that there is wiggle room in
8.5.3 to allow EDG's behavior.  More specifically, EDG is choosing this bullet:

*  The reference is bound to the object represented by the rvalue (see
basic.lval) or to a sub-object within that object.

And (I'm still guessing) this choice requires access checking of the copy ctor,
but does not require an implicit copy ctor.  Sorry my initial post wasn't more
clear.  This is a confusing area to me.


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=25950



[Bug c++/25950] [3.4/4.0/4.1 Regression] [DR 391] Reference binding and explicit copy constructors

2006-01-24 Thread hhinnant at apple dot com


--- Comment #6 from hhinnant at apple dot com  2006-01-25 02:05 ---
At the risk of continuing off-topic...

Thank you Andrew for your continuing prompt and high quality work.  It is a
very valuable service and I've never had any complaints with the way you
provide it.  Good Job and Thank You!


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=25950



[Bug c++/25950] [3.4/4.0/4.1] [DR 391] Reference binding and explicit copy constructors

2006-01-24 Thread hhinnant at apple dot com


--- Comment #9 from hhinnant at apple dot com  2006-01-25 02:54 ---
(In reply to comment #8)
 Changing to request for enhancement.  The requested behaviour is a change
 in th working paper.  Existing behaviour is what is required by the standard
 (even when it can be argued that checking for something that is elided is
 suboptimal.)

Did you read comment 3? 


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=25950



[Bug c++/25950] [3.4/4.0/4.1] [DR 392] Reference binding and explicit copy constructors

2006-01-24 Thread hhinnant at apple dot com


--- Comment #13 from hhinnant at apple dot com  2006-01-25 03:24 ---
(In reply to comment #11)
 | Did you read comment 3? 
 
 Yes.  Is your claim that whether the copy constructor is converting or
 not does not matter? 

No.  My suspicion is that there is a 99.99% chance that EDG is conforming to
C++03 in this regard.  And furthermore, their behavior (which is different from
ours) is preferable to our customers.


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=25950



[Bug libstdc++/25913] New: Client's isnormal function is broken by cmath

2006-01-22 Thread hhinnant at apple dot com
I believe the program below should compile:

#include cmath
#include string

struct employee
: private std::string
{
};

struct manager
: public employee
{
};

bool isnormal(const employee e)
{
return false;
}

int main()
{
manager m;
bool b = isnormal(m);
}

cmath: error: invalid cast from type 'manager' to type 'double'


-- 
   Summary: Client's isnormal function is broken by cmath
   Product: gcc
   Version: 4.0.1
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: libstdc++
AssignedTo: unassigned at gcc dot gnu dot org
ReportedBy: hhinnant at apple dot com


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=25913



[Bug libstdc++/25913] Client's isnormal function is broken by cmath

2006-01-22 Thread hhinnant at apple dot com


--- Comment #2 from hhinnant at apple dot com  2006-01-22 20:25 ---
(In reply to comment #1)
 
 Does the problem exist if you configure with --disable-c99?

I haven't tried that configuration.  The docs say that setting may change
libstdc++'s ABI.

So this is expected behavior for the default configuration?


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=25913



[Bug libstdc++/25913] Client's isnormal function is broken by cmath

2006-01-22 Thread hhinnant at apple dot com


--- Comment #4 from hhinnant at apple dot com  2006-01-22 20:49 ---
(In reply to comment #3)

   (3) even when isnormal is enable-if hacked, you still potentially
   run into the same problem.

For example?


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=25913



[Bug c++/25894] New: conditional operator operating on derived / base pointers appears incorrect

2006-01-20 Thread hhinnant at apple dot com
Consider this program:

class base {
public:
base() {}
private:
int val_;
};

class derived : public base {
public:
derived() {}
};

template bool struct static_assert;
template  struct static_asserttrue {};

int main ()
{
static const bool x = true ? (derived*)0 : (base*)0;
static_assert!x test;
}

I'm expecting it to compile (EDG compiles it).  The current error I get is:

error: 'x' cannot appear in a constant-expression

If I allow run time evaluation of x, and print it out, I get 1 instead of 0 as
I expect.


-- 
   Summary: conditional operator operating on derived / base
pointers appears incorrect
   Product: gcc
   Version: 4.0.1
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
AssignedTo: unassigned at gcc dot gnu dot org
ReportedBy: hhinnant at apple dot com


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=25894



[Bug libstdc++/25191] exception_defines.h #defines try/catch

2006-01-11 Thread hhinnant at apple dot com


--- Comment #22 from hhinnant at apple dot com  2006-01-11 15:30 ---
Conforming C++ programs exist that work correctly with -fno-exceptions as long
as they don't include any libstdc++ header.  These same programs can fail (at
either compile time or run time) if they also include some (not all) libstdc++
header.

For example:

#include stdio.h

#define glue(a, b)  a ## b
#define xglue(a, b) glue(a, b)
#define tryLOW hello
#define LOW LOW , world

int main()
{
printf(%s\n, xglue(try, LOW));
}

This is a conforming C++ program.  It should run and print out:

hello, world

And it does so for gcc whether or not -fno-exceptions.

However if the same program includes vector or iostream (just as an
example), then the program runs only if -fno-exceptions is not specified. 
Otherwise:

/Volumes/Data/Development/XcTest/main.cpp:12:1: error: pasting ) and LOW
does not give a valid preprocessing token
/Volumes/Data/Development/XcTest/main.cpp: In function 'int main()':
/Volumes/Data/Development/XcTest/main.cpp:12: error: expected
primary-expression before 'if'

#define'ing try and catch is non-conforming.


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=25191




[Bug libstdc++/25191] exception_defines.h #defines try/catch

2006-01-11 Thread hhinnant at apple dot com


--- Comment #24 from hhinnant at apple dot com  2006-01-11 16:10 ---
(In reply to comment #23)
 You forgot to mentin that -fno-exceptions is neither mandated, nor
 required to work with programs that play tricks with try/catch.
 So, your assertion is unfounded.

The demo program does not play tricks with try/catch.  It uses the identifier
try in a completely conforming manner.

What subset of C++ programs do we expect to work under -fno-exceptions?  And
where is that documented?  The only thing I can find in our documentation that
addresses my question is:

You may also wish to disable this option if you are compiling older
C++ programs that don't use exception handling. 

My demo is exactly that:  A C++ program that does not use exception handling
(and yet is still conforming).  And gcc (without libstdc++) handles it just
fine.

Where do we document that some, but not all libstdc++ headers change the
semantics of -fno-exception (as gcc documents it) and may render some
conforming C++ programs broken?


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=25191




[Bug libstdc++/25191] exception_defines.h #defines try/catch

2006-01-11 Thread hhinnant at apple dot com


--- Comment #26 from hhinnant at apple dot com  2006-01-11 18:02 ---
(In reply to comment #25)
 Subject: Re:  exception_defines.h #defines try/catch
 | The demo program does not play tricks with try/catch.
 
 It does, with xlgue(try, ).

No, try in this context is not a keyword.  There is no try, no catch, no
exception, in this conforming C++ program.

 | What subset of C++ programs do we expect to work under -fno-exceptions?
 
 Those that understand that try/catch are special.

The intent of turning off exception handling in the compiler is to accomidate
programs that are ignorant of try/catch, and have no need to process
exceptions.

 Can you provide standard specs that says the program must work with
 -fno-exceptions?

Of course not.  Does this imply that we ought to lower our expectations of our
product when exceptions are disabled such that it will seemingly randomly break
conforming code?  Or are our quality standards higher than that?

 | Where do we document that some, but not all libstdc++ headers change the
 | semantics of -fno-exception (as gcc documents it) and may render some
 | conforming C++ programs broken?
 
 If the issue is that -fno-exceptions is not well documented, then we
 should document it better.  I'm happy to review documentation patches
 that reflect the current state. 

I would rather not document that the libstdc++ takes a position contrary to the
compiler and does not work with exception-ignorant but conforming code with
-fno-exceptions.  Such a position would be hard to justify.


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=25191



[Bug libstdc++/25191] exception_defines.h #defines try/catch

2006-01-11 Thread hhinnant at apple dot com


--- Comment #33 from hhinnant at apple dot com  2006-01-12 02:49 ---
(In reply to comment #32)
 As I said before, there is still a diagnostic issue and now it is worse 
 with
 doing that in the front-end since people don't read docs that well so 
 we will
 be getting bug reports about try/catch not doing the correct thing when
 -fno-exceptions is supplied (yes I am serious).

Yes, excellent point.  Let's back up a minute:

What do we want to happen for this program (under -fno-exceptions)?

int main()
{
try
{
}
catch (...)
{
}
}

?

My recommendation would be something along the lines of:

error: exception handling disabled, use -fexceptions to enable

(which is what currently happens, good job all around).

Now:  what do we want to happen for this program:

#include vector

int main()
{
try
{
}
catch (...)
{
}
}

?

My recommendation:  Same as the last program.  Today's results:  Compiles with
no diagnostic.

I don't think this is the best quality that we can offer, mainly due to the
difference in behavior by merely including vector.

So it comes back to the first example:  What is the best solution for the
customer if try/catch is used with -fno-exceptions?  Perhaps I am wrong that an
error is best?  What do other compilers do in this situation?

EDG:

ComeauTest.c, line 3: error: support for exception handling is disabled
  try
  ^

CodeWarrior:

Error   : exception handling option is disabled
HelloWorld.cp line 4{ 

If I'm wrong about a diagnostic being preferrable, I'm in good company.  And
both of these products give the same result if vector is included.

If there is to be a front end fix, it would have to be special for #pragma GCC
system_header.  Just seems like a lot of fuss just so you can read try
instead of __try in a libstdc++ header.  But I have no objection to someone
fixing the front end that way.


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=25191



[Bug libstdc++/25466] New: typeid expression fails to throw bad_typeid according to 5.2.8p2

2005-12-17 Thread hhinnant at apple dot com
5.2.8p2 says that if a typeid expression refers to a polymorphic type and the
expression is formed by dereferencing a null pointer that a bad_typeid should
be thrown.

#include iostream
#include typeinfo

template class T
bool is_polymorphic() {
   bool result(false);
   typeid( (result=true), *(T*)0);
   return result;
}

struct non_polymorphic {};
struct polymorphic { virtual ~polymorphic() {} };


int main() {
   std::cout  is_polymorphicint()  '\n';
   std::cout  is_polymorphicnon_polymorphic()  '\n';
   try
   {
  std::cout  is_polymorphicpolymorphic()  '\n';  //3
  std::cout  Fail, should have thrown bad_typeid\n;
   }
   catch (std::bad_typeid)
   {
  std::cout  Pass\n;
   }
   catch (...)
   {
  std::cout  Fail, bad_typeid not caught\n;
   }
}

Expected output:

0
0
Pass

Output received with gcc 4.0.1

0
0
1
Fail, should have thrown bad_typeid


-- 
   Summary: typeid expression fails to throw bad_typeid according to
5.2.8p2
   Product: gcc
   Version: 4.0.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: libstdc++
AssignedTo: unassigned at gcc dot gnu dot org
ReportedBy: hhinnant at apple dot com


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=25466



[Bug libstdc++/25467] New: typeid expression fails to throw bad_typeid according to 5.2.8p2

2005-12-17 Thread hhinnant at apple dot com
5.2.8p2 says that if a typeid expression refers to a polymorphic type and the
expression is formed by dereferencing a null pointer that a bad_typeid should
be thrown.

#include iostream
#include typeinfo

template class T
bool is_polymorphic() {
   bool result(false);
   typeid( (result=true), *(T*)0);
   return result;
}

struct non_polymorphic {};
struct polymorphic { virtual ~polymorphic() {} };


int main() {
   std::cout  is_polymorphicint()  '\n';
   std::cout  is_polymorphicnon_polymorphic()  '\n';
   try
   {
  std::cout  is_polymorphicpolymorphic()  '\n';  //3
  std::cout  Fail, should have thrown bad_typeid\n;
   }
   catch (std::bad_typeid)
   {
  std::cout  Pass\n;
   }
   catch (...)
   {
  std::cout  Fail, bad_typeid not caught\n;
   }
}

Expected output:

0
0
Pass

Output received with gcc 4.0.1

0
0
1
Fail, should have thrown bad_typeid


-- 
   Summary: typeid expression fails to throw bad_typeid according to
5.2.8p2
   Product: gcc
   Version: 4.0.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: libstdc++
AssignedTo: unassigned at gcc dot gnu dot org
ReportedBy: hhinnant at apple dot com


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=25467



[Bug c++/25466] typeid expression fails to throw bad_typeid according to 5.2.8p2

2005-12-17 Thread hhinnant at apple dot com


--- Comment #4 from hhinnant at apple dot com  2005-12-17 22:01 ---
Agreed, (that's brutal ;-) ).

Sorry about the duplicate.  My clumsy fingers hit refresh on my browser and
that generated the duplicate.


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=25466



[Bug libstdc++/25191] exception_defines.h #defines try/catch

2005-12-05 Thread hhinnant at apple dot com


--- Comment #19 from hhinnant at apple dot com  2005-12-06 01:19 ---
(In reply to comment #17)
 Subject: Re:  exception_defines.h #defines try/catch
 
 hhinnant at apple dot com [EMAIL PROTECTED] writes:
 
 | I don't know what that means.  Or even how it would be relevant.  ObjC++ is
 | what it is.  If you or I don't like ObjC++, is that relevant?
 
 I'm quite disappointed you reduced this issue to liking/disliking ObjC++.
 If you believe that is the appropriate reduction, this is my last
 message on the issue.  The rest clarifies what I said earlier.

Message #16, starting with the paragaph:

 This PR is about the fact...

states what I think this issue reduces to.

 This issue has nothing to do with liking or disliking ObjC++, not
 matter how much of hostility or other emotion you would like to
 inject into it.

I'm sorry if you find my vocabulary offensive, even after I've politely
explained myself.  customer-friendly and customer-hostile are terms I've
used for a long time.  I find them self explanatory, to the point, and not
inflamatory.  Would customer-friendly and not customer-friendly work better
for you?  I'm certainly willing to change my vocabulary.

 ObjC++ got it wrong, it got it wrong.  The place to
 fix it is in ObjC++.  That has nothing to do with liking or disliking
 ObjC++. 

How did ObjC++ get it wrong?  And what is it?

 I would not guess that it is partly because you seem to approach the
 issue only from ObjC++-centric point of view.

chuckle  I would not guess that either, considering my background.  Indeed
I'm trying my best not to approach this from a C++ centric point of view.

 This is issue is not
 just fixing ObjC++ by uglifying libstdc++.  Those macro definitions of
 try/catch when -fno-exceptions have been there long before ObjC++ came
 in.  It is not like we're suddenly changing them.  
 The uglification you're proposing is also breaking interfaces:  All
 user codes that worked with both -fexceptions and -fno-exceptions and
 used try/catch now will break.  I don't think I'm prepared to accept
 that breakage.

Thank you for pointing me to our documentation.  We apparently do not document
the behavior you want to preserve.  Therefore we will not be breaking anything.
 If user code is using try/catch and -fno-exceptions at the same time, it is
doing so at its own peril.  Simply omitting a standard header from the
customer's code could change compiling code into non-compiling code.

#include limits  // breaks under -fno-excetions if this header is removed

void foo()
{
 try 
{
 bar();
}
catch (...)
{
}
}

  The fix is simple for ObjC++: #undef them if it thinks
 it wants both -fno-exceptions, libstdc++ headers.

If this fix were simple, then great.  But it isn't simple because each ObjC++
customer has to re-implement it, and not just in one place, but in every single
translation unit.  And it doesn't even work in general if ObjC++ headers can
contain @try/@catch and contain std::lib includes:

// C++ includes
#include list
#include vector

// Obj C includes
#undef try
#undef catch
#import my_header.h   // oops, my_header.h includes iostream!

That's a maintenance nightmare for the ObjC++ customer!  And the reason we put
the customer through this is so that we can read try instead of __try in
the libstdc++ implementation?

If we really wanted to fix this right, we'd get rid of 95% of the try/catch
clauses in the first place (via RAII techniques).  Then we wouldn't have to
read try or __try (except very rarely).

-Howard


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=25191



[Bug libstdc++/25191] exception_defines.h #defines try/catch

2005-12-04 Thread hhinnant at apple dot com


--- Comment #18 from hhinnant at apple dot com  2005-12-04 15:55 ---
(In reply to comment #15)
 Subject: Re:  exception_defines.h #defines try/catch
 It is also a simple fact
 that GCC documents what happens with -fno-exceptions.

I'm trying to find this documentation.  So far all I've found is:

http://gcc.gnu.org/onlinedocs/gcc/Code-Gen-Options.html#Code-Gen-Options

-fexceptions
Enable exception handling

Is there more?

Thanks,
Howard


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=25191



[Bug libstdc++/25191] exception_defines.h #defines try/catch

2005-12-03 Thread hhinnant at apple dot com


--- Comment #16 from hhinnant at apple dot com  2005-12-04 02:12 ---
(In reply to comment #15)
 Subject: Re:  exception_defines.h #defines try/catch
 
 I don't think anybody is disputing that.  It is also a simple fact
 that GCC documents what happens with -fno-exceptions.

I think it is good that gcc documents what it does, and I am also impressed
with the gcc documentation in general.  But just because something is
documented doesn't make it the best answer.  Thank you for letting me know this
behaivor is documented (I hadn't even tried to look that up, and still haven't
found it).  It is still a customer-hostile solution.

 Trying not to abide by the rules and getting back and shouting for
 hostility is a joke.  A sad one, Howard :-(

I'm not shouting (no caps, not even an exlamation point), but perhaps my
vocabulary needs explaining.  I'm a pretty simple guy.  And I'm also very
customer focused in everything I do (even in situations that are not
traditionally vendor/customer).  If a solution seems to work for customers very
well, I'll often call it customer-friendly.  If a solution seems to work for
customers very poorly, I'll often call it customer-hostile.  I'm not trying to
shout or make any jokes.  It is simply the way I work.  My apologies for not
explaining that up front.

But I won't apologize for being customer focused.  That focus has served me
well over the past two decades.  If I provide a service, and those who I'm
providing the service to don't find that service useful, I'll look inward first
- every single time.  I'll continue to think about solutions from the
customer's viewpoint as best I am able.  And if or when I ever find myself
having trouble doing that, I pray I'm able to retire.

 No. ObjC++ is messing with itself.

I don't know what that means.  Or even how it would be relevant.  ObjC++ is
what it is.  If you or I don't like ObjC++, is that relevant?

 Either you don't want to use it, and you don't.  Or you want to use it
 and you have to abide by what it does.  

Maybe it does the wrong thing.  We have customer complaints.

 Then, why what is this PR is about in the first place?

My bad for not explaining it better in the original post.

This PR is about the fact that although our customers find the compiler's
definition of -fno-exceptions useful, and want use it, but they find the
libstdc++'s reaction to this compiler flag unhelpful.  Furthermore, making
libstdc++'s behavior under -fno-exceptions to actually be useful for our
customers is nearly trivial.  Yes readability takes a minor hit.  But
functionality/usefulness increases.

I really don't even understand why this is controversial.  This is a minor
issue that will have absolutely no impact on our C++ customers, and will make
our ObjC++ customers much happier.  If someone had raised a point about how we
are harming our C++ customers with this fix, I would have been alarmed and
searched for a solution that didn't harm our C++ customers.  If it was a major
imposition from an implementation point of view, I would be alarmed.  But as it
is, all I'm hearing is that there is an objection to helping our ObjC++
customers at the expense of a very minor readability hit in libstdc++
internals.  I'm honestly very confused by that response.

-Howard


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=25191



[Bug libstdc++/25191] exception_defines.h #defines try/catch

2005-12-02 Thread hhinnant at apple dot com


--- Comment #5 from hhinnant at apple dot com  2005-12-02 19:07 ---
(In reply to comment #2)
 I'd rather you work around this in objective-c or objective c++.

How?  I'm open to suggestions.

-Howard


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=25191



[Bug libstdc++/25191] exception_defines.h #defines try/catch

2005-12-02 Thread hhinnant at apple dot com


--- Comment #9 from hhinnant at apple dot com  2005-12-02 21:00 ---
(In reply to comment #8)
 Subject: Re:  exception_defines.h #defines try/catch
 
 hhinnant at apple dot com [EMAIL PROTECTED] writes:
 
 | --- Comment #5 from hhinnant at apple dot com  2005-12-02 19:07 ---
 | (In reply to comment #2)
 |  I'd rather you work around this in objective-c or objective c++.
 | 
 | How?  I'm open to suggestions.
 
 #undef them if you intend to include libstdc++ files and use try/catch
 with funny characters to mean something else with -fno-exceptions?

I'm sorry, I'm just not understanding what you're suggesting.  If you could
expound on your suggestion I would be most appreciative.  If it helps, here is
a demo file that I would like to have work with -fno-exceptions.

#include list
#include vector
#import Cocoa/Cocoa.h
#import my_header.h  // may have contain ObjC @try/@catch
#include iostream

int main()
{
//
}

An alternative to my original suggested fix is to solve this problem in the FE
by parsing try/catch differently (e.g. as if they were if(true)/if(false)) in
system headers when -fno-exceptions.  Then we could just get rid of
exception_defines.h, and still have pretty std::headers.  Not being someone
with a lot of FE experience, I have more hesitation about this latter approach.


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=25191



[Bug libstdc++/25191] exception_defines.h #defines try/catch

2005-12-02 Thread hhinnant at apple dot com


--- Comment #11 from hhinnant at apple dot com  2005-12-02 21:21 ---
(In reply to comment #10)
 (In reply to comment #9)
  Not being someone with a lot of FE experience, I have more hesitation about 
  this latter approach.
 
 That solution still does not solve my issue of the diagnostic issue.  

Doesn't it?  try/catch is no longer #defined, and client code will get a
diagnostic if it uses try/catch with -fno-exceptions (only the system headers
get special treatment by the FE).  That's what we want, right?

 
 We really should not be defining keywords in the headers at all.  If we define
 bool somewhere to be int, we would get incorrect behavior the same way we are
 getting for try/catch.
 

nod  That's always been a golden rule that has worked well for me (after
learning it the hard way many moons ago ;-) ).

-Howard


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=25191



[Bug libstdc++/25191] exception_defines.h #defines try/catch

2005-12-02 Thread hhinnant at apple dot com


--- Comment #14 from hhinnant at apple dot com  2005-12-03 01:25 ---
(In reply to comment #13)
 Subject: Re:  exception_defines.h #defines try/catch
 
 I'm saying that if you're intending to use try/catch and yet not
 want what the mean in standard C++, nor what they would mean in GNU
 C++ with -fno-exceptions, then you have to watch what you're doing.
 Meaning, in your *own* codes, you #undef try/catch.  Whether it is in
 Cocoa.h or foobar.c, I don't care.  Just take your responsability to
 #undef them -- because you have decided to have mean something else.
 I'm not inclined in seeing the libstdc++ be uglified in that direction.

I see, thanks for the clarification.

It is my understanding that gcc 4.1 supports a language called Obj C++.  In
this language (and I am by no means an Obj C++ expert) you can pretty much mix
 match Obj C and C++.  I have customers using Obj C++ who want to turn off C++
exception support, but retain Obj C exception support.  They can easily do so
-- unless they include a libstdc++ header.  The libstdc++ headers are messing
up their ObjC @try/@catch statements.  That is, libstdc++ is not supportive of
ObjC++ in this manner.

They are not trying to use C++ try/catch in a bizarre or unsupported manner. 
They are simply trying to use ObjC++ exceptions without the unwanted cost of
C++ exceptions.

This is quite analogous to the C headers compiled under C++.  math.h, under
C++, is supposed to behave a little differently than math.h under C.  As a
C++ programmer I appreciate that some C vendors will make some modest
accomadations for me.

This seems to me like a very modest accomadation we can make for the ObjC++
programmer.  Afterall, ObjC++ is a supported language of gcc now, and libstdc++
is part of that support.  Asking every ObjC++ programmer to order the C++ and
ObjC headers and #undef things just right seems quite error prone to me when we
can easily solve the problem once and for all.

// C++ includes
#include list
#include vector

// Obj C includes
#undef try
#undef catch
#import Cocoa/Cocoa.h
#import my_header.h 
#include iostream // oops, put C++ header in wrong place!

int main()
{
//
}

That is a customer-hostile solution.

-Howard


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=25191



[Bug c++/25191] New: exception_defines.h #defines try/catch

2005-11-30 Thread hhinnant at apple dot com
exception_defines.h #defines try/catch when -fno-exceptions.  This destroys
Objective C code using @try and @catch.  A simple fix is to insteaad in
exception_defines.h do something like (untested):

#ifndef __EXCEPTIONS
// Iff -fno-exceptions, transform error handling code to work without it.
# define __try  if (true)
# define __catch(X) if (false)
# define __throw_exception_again
#else
// Else proceed normally.
# define __try  try
# define __catch(X) catch(X)
# define __throw_exception_again throw
#endif

And then religiously use __try/__catch in libstdc++ instead of try/catch.


-- 
   Summary: exception_defines.h #defines try/catch
   Product: gcc
   Version: 4.0.1
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
AssignedTo: unassigned at gcc dot gnu dot org
ReportedBy: hhinnant at apple dot com


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=25191



[Bug libstdc++/24803] tr1::reference_wrapper and pointers to member functions

2005-11-12 Thread hhinnant at apple dot com


--- Comment #5 from hhinnant at apple dot com  2005-11-12 19:02 ---
   (1) Strong-arm a C++ front-end guru into implementing rvalue references,
   then use them in the TR1 function objects. Heck, we'll need 'em
   for C++0x anyway :)

At the risk of being reckless.  Yes...  well, more like YES!!!  ;-)

I know very little about gcc at this point.  But if the feature is implemented
under a pragma (say rvalue_refs), default off, and if library code can test the
pragma (at the preprocessor level), then we could really move forward (let the
puns lie where they may).  N1855 went through core review in Mont Tremblant. 
There were several good suggestions on rewording the proposed words, but
absolutely nothing against the functionality or even the syntax.  That doesn't
mean the syntax is set in concrete.  But it does mean the mud is firming up. 
(I am guessing) It will take effort now for N1855 to not be accepted as is, or
pretty darn close to it.  The lwg also voiced no complaints and indeed strong
support for N1856 - N1862.  Almost irritation that I was taking up committee
time with this stuff again (just do it!).

If the language and library work goes under a pragma, default off, we can do
the following:

1.  Code like (for reference_wrapper):

#ifdef _GCC_MOVE
operator()(T1 t1) const {return (*data_)(std::forwardT1(t1));}
#else
operator()(T1 t1) const {return (*data_)(t1);}
#endif

2.  When bug reports like this come in, say try turning on rvalue reference
(give instructions for doing that).

3.  If the syntax or functionality of the language changes, we are relatively
free to change the compiler/lib, documenting as appropriate, since this is not
default behavior, and should be documented as an extension - which could change
in the future.

4.  When it becomes standard, we set the pragma to default on.

Dealing with bugs like this via hacks is more work than doing it right with
rvalue reference.

So who are going to get?  I'd love to do it.  But I'm slightly worse than a
newbie in this area.  I could write language tests for it though.  I also
wouldn't mind following someone more experienced just for my own education.

How about Russell Yanofsky?

http://russ.hn.org/rref/

It would be best if one did not have to recompile libstdc++ when flipping this
pragma.  In order to achieve that you have to be committed to keeping as much
out of the binary lib as possible.  To date the direction of libstdc++ has been
just the opposite.


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=24803



[Bug c++/24758] New: Non ambiguous typedefs

2005-11-09 Thread hhinnant at apple dot com
Here's the test case:
---
typedef unsigned short ushort;

namespace X
{
typedef unsigned short ushort;
}

using namespace X;

int main()
{
ushort us = 0;
}
---
prompt g++ main.cpp

main.cpp: In function 'int main()':
main.cpp:12: error: 'ushort' was not declared in this scope
main.cpp:12: error: expected `;' before 'us'

I'm expecting a clean compile (and it does compile cleanly with CW and Comeau).

The deal is that the typedef ushort is defined in two different places, to the
same type, and then brought in conflict via a using declaration.  But since
the two typedefs refer to the same type, I expect that the compiler will see
that there is no conflict, and proceed without error or warning (reference
C++03 7.1.3p2).

Had the two typedefs referred to different types, I expect the compiler to
complain about an ambiguity, for example:

typedef unsigned short ushort;

namespace X
{
typedef short ushort;
}

using namespace X;

int main()
{
ushort us = 0;
}

error: ambiguous access to name found 'ushort' and 'X::ushort'

This bug is important as client code commonly includes system headers which
create a lot of common typedefs in the global namespace.  If the user also
(unknowingly) creates the same typedefs, and if there is no conflict, there
should be no error.  If there is a conflict, the error message should be a lot
more helpful than it currently is.


-- 
   Summary: Non ambiguous typedefs
   Product: gcc
   Version: 4.0.1
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
AssignedTo: unassigned at gcc dot gnu dot org
ReportedBy: hhinnant at apple dot com


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=24758