Re: Gfortran and using C99 cbrt for X ** (1./3.)

2006-12-04 Thread Howard Hinnant

On Dec 4, 2006, at 11:27 AM, Richard Guenther wrote:


On 12/3/06, Toon Moene <[EMAIL PROTECTED]> wrote:

Richard,

Somewhere, in a mail lost in my large e-mail clash with my ISP
(verizon), you said that gfortran couldn't profit from the pow(x,  
1./3.)

-> cbrt(x) conversion because gfortran didn't "know" of cbrt.

Could you be more explicit about this - I'd like to repair this
deficiency, if at all possible.

Thanks in advance !


It's a matter of making the cbrt builtin available - I have a patch  
for this,
but wondered if the fortran frontend can rely on the cbrt library  
call being
available?  Or available in a fast variant, not a fallback  
implementation in
libgfortran which does pow (x, 1./3.) which will then of course  
pessimize

pow (x, 2./3.) -> tmp = cbrt(x); tmp * tmp  expansion.


Is pow(x, 1./3.) == cbrt(x) ?

My handheld calculator says (imagining a 3 decimal digit machine):

pow(64.0, .333) == 3.99

In other words, can pow assume that if it sees .333, that the client  
actually meant the non-representable 1/3?  Or must pow assume that . 
333 means .333?  My inclination is that if pow(x, 1./3.) (computed  
correctly to the last bit) ever differs from cbrt(x) (computed  
correctly to the last bit) then this substitution should not be done.


-Howard



Re: Gfortran and using C99 cbrt for X ** (1./3.)

2006-12-04 Thread Howard Hinnant

On Dec 4, 2006, at 4:57 PM, Richard Guenther wrote:




My inclination is that if pow(x, 1./3.) (computed
correctly to the last bit) ever differs from cbrt(x) (computed
correctly to the last bit) then this substitution should not be done.


C99 7.12.7.1 says "The cbrt functions compute the real cube root
of x." and "The cbrt functions return x**1/3".  So it looks to me
that cbrt is required to return the same as pow(x, 1/3).


 For me, this:

#include 
#include 

int main()
{
printf("pow(100., 1./3.) = %a\ncbrt(100.)   = %a\n",  
pow(100., 1./3.), cbrt(100.));

}

prints out:

pow(100., 1./3.) = 0x1.8fffep+6
cbrt(100.)   = 0x1.9p+6

I suspect that both are correct, rounded to the nearest least  
significant bit.  Admittedly I haven't checked the computation by  
hand for pow(100., 1./3.).  But I did the computation using gcc  
4.0 on both PPC and Intel Mac hardware, and on PPC using CodeWarrior  
math libs, and got the same results on all three platforms.


The pow function is not raising 1,000,000 to the power of 1/3.  It is  
raising 1,000,000 to some power which is very close to, but not equal  
to 1/3.


Perhaps I've misunderstood and you have some way of exactly  
representing the fraction 1/3 in Gfortran.  In C and C++ we have no  
way to exactly represent that fraction except implicitly using cbrt.  
(or with a user-defined rational type)


-Howard



Re: Gfortran and using C99 cbrt for X ** (1./3.)

2006-12-04 Thread Howard Hinnant

On Dec 4, 2006, at 6:08 PM, Richard Guenther wrote:


The question
is whether a correctly rounded "exact" cbrt differs from the pow
replacement by more than 1ulp - it looks like this is not the case.


If that is the question, I'm afraid your answer is not accurate.  In  
the example I showed the difference is 2 ulp.  The difference appears  
to grow with the magnitude of the argument.  On my systems, when the  
argument is DBL_MAX, the difference is 75 ulp.


pow(DBL_MAX, 1./3.) = 0x1.428a2f98d7240p+341
cbrt(DBL_MAX)   = 0x1.428a2f98d728bp+341

And yes, I agree with you about the C99 standard.  It allows the  
vendor to compute pretty much any answer it wants from either pow or  
cbrt.  Accuracy is not mandated.  And I'm not trying to mandate  
accuracy for Gfortran either.  I just had a knee jerk reaction when I  
read that pow(x, 1./3.) could be optimized to cbrt(x) (and on re- 
reading, perhaps I inferred too much right there).  This isn't just  
an optimization.  It is also an approximation.  Perhaps that is  
acceptable.  I'm only highlighting the fact in case it might be  
important but not recognized.


-Howard



Re: compile time enforcement of exception specification

2007-01-14 Thread Howard Hinnant
At the risk of wading in too deep... there is one aspect of exception  
specification checking that I've become absolutely convinced would  
benefit greatly from static checking:


A::~A() static throw();  // or whatever syntax

That is, there is some code that you know should not throw anything,  
and it would be most helpful if one could get compiler help on that.   
If it throws an exception, it really doesn't matter what it throws.   
If it doesn't throw an exception, that is a crucial property to  
writing code with known exception safety guarantees (basic, strong,  
nothrow).


If I write something like a destructor, move constructor or copy  
constructor with an empty throw spec, it isn't because I want  
unexpected() to be called just in case some exception is called.  It  
is because I want to broadcast that this function can't fail.  But  
that's not what C++ says an empty throw spec means.


For some code, it is essential that it have a "no fail" property.   
That includes C++ destructors and "finally clauses" in other  
languages.  Automated help in this department would be incredibly  
valuable.  Being alerted that code you thought was nothrow has  
suddenly become throwing because of a remote change in some function  
you're calling would greatly aid robustness (much like const  
correctness does today).  Otoh if some remote function changes from  
throwing X to throwing Y, that's really not going to impact the  
client's fundamental design (though it is an API-breaking change).


In a nutshell, if I write:

struct A
{
int data_;
int get_data() const static throw() {return data_;} // or  
whatever syntax for throw()

};

I'd like a diagnostic if get_data() generates code to call  
std::unexpected().


-Howard



backslash whitespace newline

2005-10-24 Thread Howard Hinnant
I've been reviewing the age-old issue of interpreting  
* as the end-of-line indicator as is the current  
practice with gcc.  For those not familiar with this issue, gcc takes  
advantage of C99's 5.1.1.2p1b1 "implementation-defined manner" to  
convert multibyte end-of-line indicators to newline characters.  gcc  
considers zero or more whitespace characters preceding a more  
traditional CR and/or LF as the end-of-line indicator.  This behavior  
can cause differences in some code compared to compilers which do not  
strip trailing whitespace off of lines.  For example:


// comment \
int x;
int y;

Pretend there's one or more spaces or tabs after the '\'.  gcc will  
interpret this as:


A:

// comment int x;
int y;

while other compilers (Microsoft, EDG-based, CodeWarrior to name a  
few) interpret it as:


B:

// comment
int x;
int y;

And depending on what you're trying to do, either A or B is the  
"correct" answer.  I've seen code broken either way (by assuming A  
and having the compiler do B and vice-versa).


This issue has recently been discussed on the C standards reflector,  
and though I was not privy to that discussion, my understanding is  
that the likely resolution from this standards body will be that a  
compiler implementing either A or B is conforming.


That being said, gcc to the best of knowledge, is the only modern  
compiler to implement end-of-line whitespace stripping (yes I'm aware  
of older compilers and dealing with punch cards). So on the basis of  
conforming to a de-facto standard alone, I propose that gcc abandon  
end-of-line whitespace stripping, or at least strip 2 or more  
whitespace characters down to 1 space instead of to 0 spaces during  
translation phase 1.


I realize that this change could break some existing code.  But I am  
also aware of existing code wishing to port to gcc which is broken by  
gcc's current behavior.  If we want gcc to "gain market share", does  
it not make sense to "welcome" new comers when possible by adopting  
what is otherwise industry-wide practice?


Thanks,
Howard



Re: backslash whitespace newline

2005-10-25 Thread Howard Hinnant

On Oct 25, 2005, at 6:22 PM, Andrew Pinski wrote:

We have people already complaining about removing extensions.  Why  
should we change

this implementionation defined documented behavior.


I'm not convinced that "extension" is a proper term for this  
behavior.  It is more like an incompatibility with the rest of the  
world's compilers.  The reason for change is to conform to a de-facto  
standard, and thus ease the migration of future gcc customers to our  
compiler.


These hypothetical customers coming from MS, EDG-based, or  
CodeWarrior compilers might have code that looks like:


// A poorly formatted comment \\
int x = 0;
int y = 1;
...

Note I'm not trying to defend code that looks like this.  But the  
fact is that if you've got a million lines of code that's been  
compiling with a non-gcc compiler for a decade, silly things like  
this tend to add an extra hurdle to porting to gcc.


I don't claim that gcc's behavior is better or worse than everyone  
else's.  I only claim that gcc is unique in this regard, and that  
isn't a good thing if you're trying to be friendly to customers  
wanting to adopt your product.


-Howard



Re: backslash whitespace newline

2005-10-25 Thread Howard Hinnant

On Oct 25, 2005, at 7:44 PM, Andrew Pinski wrote:

But this is not an extension at all.  This is an implementation  
defined

behavior which is different than what an extension would do.

People depending on this is not the correct thing do any ways as
there could be another compiler besides which GCC which does this.


  I'm not disagreeing with anything you're saying.  My only  
point is that it might be in gcc's best interest to have the same  
implementation defined behavior as MS, EDG-based compilers and  
CodeWarrior when that is a reasonable choice (and probably others, I  
know my list of compilers is incomplete).


-Howard



Re: backslash whitespace newline

2005-10-25 Thread Howard Hinnant


On Oct 25, 2005, at 8:11 PM, Joe Buck wrote:


// A poorly formatted comment \\
int x = 0;
int y = 1;
...



Howard,

Have you tested the sequence above with various compilers?


I only know of the results on gcc 4.x, MS, EDG-based, and Freescale  
CodeWarrior.



I just
have.  The behavior depends on whether there is whitespace after the
\\ or not.  If there is none, then EDG-based compilers will comment
out the declaration of x.  If there is whitespace, gcc 3.x comments
it out and the others don't.


Right, that's exactly the issue.


I personally like the fact that gcc's
behavior does not depend on invisible characters; on the other hand,
there's a good argument that this behavior is ordinarily not desirable
and should be warned about, except to continue strings.

I have difficulty believing that it is desirable for production code
to contain surprises like this.


Personally I'd fire a programmer that depended on the presence of  
whitespace after a '\'.  It is implementation defined behavior, and  
invisible in the source at that (in most editors).  I've seen code  
broken both by gcc's behavior, and by other compiler's behavior by  
depending on what happens when whitespace is included after a '\'.


And it is not my assertion that gcc's behavior is better or worse  
than other compilers.  Only that gcc's behavior is unique in the  
industry (I actually haven't tried all other modern compilers) and  
that uniqueness in this way is not an asset to gcc.


-Howard



Re: backslash whitespace newline

2005-10-25 Thread Howard Hinnant

On Oct 25, 2005, at 8:22 PM, Andrew Pinski wrote:


Why not get other compilers to change to what GCC does?  Why does GCC
have to follow what other compilers do, maybe other compilers
would be in the best interest of following what GCC does.

Why not instead get the standard changed and then GCC will just follow
then (and really should only follow at that point)?


 I'm just a pragmatic I guess.

It is only a suggestion.  And a tiny suggestion at that.  Imho, it  
would be in gcc's best interest.  I respect the fact that you feel  
otherwise.


-Howard



Re: backslash whitespace newline

2005-10-26 Thread Howard Hinnant

On Oct 26, 2005, at 12:18 PM, Robert Dewar wrote:


Mike Stump wrote:


On Oct 25, 2005, at 9:28 PM, Joe Buck wrote:

Are you really saying that someone is using ASCII line art in  
comments

that tweaks this behavior?


Yes, I'm sorry if previous message didn't make this clear.



Why would line art ever tweak this problem, why would lines
in such art have trailing white space?


Some programmers purposefully put trailing whitespace on their art in  
order to prevent translation phase 2 line splicing.  And it actually  
works everywhere but gcc.  Mind you I'm not defending this practice.   
I'm just reporting what happens in the field, and giving the opinion  
that gcc might as well adopt the same behavior as every other  
compiler ... even though the standards say it doesn't have to.


-Howard



Re: backslash whitespace newline

2005-10-26 Thread Howard Hinnant

On Oct 26, 2005, at 1:16 PM, Andrew Pinski wrote:


What I am trying to say is that
the only reason why this was brought up was because of some little
ASCII art (ASCII art does have its place in comments, see rs6000.c for
an example of where ASCII art actually helps).  If there was another
reason, like for an example someone depends on implementation defined
behavior which actually changes the meaning of the code like  
bitwise operators


I believe I may have not described the situation sufficiently  
clearly.  My apologies.


Yes, this does have to do with ASCII art.  But no, it is not simply a  
matter of messing up the comments.  Code behavior can change.  What  
was working code can stop working.  Or even worse, the code can  
compile and have different run time behavior:


int x = 0;

void f()
{
// ascii art \  
   int x = 1;
   if (x)
   do_thing1();
   else
   do_thing2();
}

If end-of-line white space is stripped in phase 1, do_thing2() is  
called.  If end-of-line white space is not stripped, do_thing1() is  
called.


-Howard



Re: What is really a new line in most compilers

2005-10-26 Thread Howard Hinnant

On Oct 26, 2005, at 4:58 PM, DJ Delorie wrote:


To add to that, Mac text files use a bare \r as a newline.


Just a nit:  5 years ago that was true.  Now \n is "native" but most  
Mac software is pretty tolerant of newline representation due to its  
history.


-Howard



Re: What is really a new line in most compilers

2005-10-26 Thread Howard Hinnant

On Oct 26, 2005, at 5:17 PM, DJ Delorie wrote:





Just a nit:  5 years ago that was true.  Now \n is "native"



Was that part of the OS/X migration, or otherwise?  Just curious.


 Part of the migration.  OS X /is/ unix.  Ok, I'm sure that's an  
inaccurate statement and I trust the more experienced Apple guys here  
will gently correct me.  But it really is... ;-)



but most Mac software is pretty tolerant of newline representation
due to its history.



Of course, that only makes it *more* of a mess, and *less* likely that
gcc is going to please everyone :-P


Yeah, I figured I should've defined "tolerant" a little better. :-)

-Howard



Re: backslash whitespace newline

2005-10-26 Thread Howard Hinnant

On Oct 26, 2005, at 6:50 PM, Robert Dewar wrote:


The problem is that it's portable to every other compiler we've
tested. I am curious what icc and xlc do, but those are the only
two not tested.



Sorry, I have a different meaning of portable, for me the term is
related to the standard, meaning that standard conforming compilers
are required to process the code correctly.

"Happens to work on (some/most/all) compilers" is not the same
thing at all for me. COmpetent programmers write portable code
by knowing what the standard requires, not by trial and error :-)


I couldn't agree with you more on that statement.  But I'll follow it  
up with:  competent tool writers make their tools so robust that even  
incompetent programmers have trouble abusing them.


Now I know that no tool is fool proof.  We all know the fools are  
getting more clever every year.  But here is a little thing we could  
do to make our tool a little more fool proof.


-Howard



Re: Call for compiler help/advice: atomic builtins for v3

2005-11-06 Thread Howard Hinnant

On Nov 6, 2005, at 6:03 AM, Paolo Carlini wrote:


So - can't you work with some preprocessor magic and a define, if
the builtins are available?

I don't really understand this last remark of yours: is it an  
alternate solution?!? Any preprocessor magic has to rely on a new  
preprocessor builtin, in case, because there is no consistent,  
unequivocal way to know whether the builtins are available for the   
actual target, we already explored that some time ago, in our  
(SUSE) gcc-development list too.


Coincidentally I also explored this option in another product.  We  
ended up implementing it and it seemed to work quite well.  It did  
require the back end to "register" with the preprocessor those  
builtins it implemented, and quite frankly I don't know exactly how  
that registration worked.  But from a library writer's point of view,  
it was pretty cool.  For example:


inline
unsigned
count_bits32(_CSTD::uint32_t x)
{
#if __has_intrinsic(__builtin_count_bits32)
return __builtin_count_bits32(x);
#else
x -= (x >> 1) & 0x;
x = (x & 0x) + ((x >> 2) & 0x);
x = (x + (x >> 4)) & 0x0F0F0F0F;
x += x >> 8;
x += x >> 16;
return (unsigned)x & 0xFF;
#endif
}

In general, if __builtin_XYZ is implemented in the BE, then  
__has_intrinsic(__builtin_XYZ) answers true, else it answers false.   
This offers a lot of generality to the library writer.  Generic  
implementations are written once and for all (in the library), and  
need not be inlined.  Furthermore, the library can test  
__has_intrinsic(__builtin_XYZ) in places relatively unrelated to   
__builtin_XYZ (such as a client of __builtin_XYZ) and perform  
different algorithms in the client depending on whether the builtin  
existed or not (clients of the atomic builtins might especially value  
such flexibility).


Also during testing the "macro-ness" of this facility can come in  
really handy:


// Test generic library "builtins"
#undef __has_intrinsic
#define __has_intrinsic(x) 0

// All __builtins are effectively disabled here,
// except of course those not protected by __has_intrinsic.

The work in the back end seems somewhat eased as well as the back end  
can completely ignore the builtin unless it wants to implement it.   
And then there is only the extra "registration" with __has_intrinsic  
to deal with.


My apologies for rehashing an old argument.  If there are pointers to:

 we already explored that some time ago, in our (SUSE) gcc- 
development list too.


I would certainly take the time to review that thread.

-Howard



non-ambiguous typedefs

2005-11-08 Thread Howard Hinnant

Hi All,

I'm wondering if the following behavior is:

1.  An already reported bug.
2.  Not reported, I need to file a bugzilla.
3.  Disputed.

Here's the test case:

typedef unsigned short ushort;

namespace X
{
typedef unsigned short ushort;
}

using namespace X;

int main()
{
ushort us = 0;
}

We currently get:

error: 'ushort' was not declared in this scope

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'

-Howard



Re: [C++] Should the complexity of std::list::size() be O(n) or O(1)?

2005-11-25 Thread Howard Hinnant

On Nov 25, 2005, at 9:28 AM, Phil Edwards wrote:


On Wed, Nov 23, 2005 at 07:42:35PM +0800, ?? wrote:


The C++ standard said Container::size() should have constant  
complexity
(ISO/IEC 14882:1998, pp. 461, Table 65), while the std::list::size 
() in
current STL of GCC is defined as { std::distance(begin(), end 
()); }, whose

complexiy is O(n).

Is it a bug?


This is a FAQ.


I could not find it here:

http://gcc.gnu.org/onlinedocs/libstdc++/faq/index.html

or here:

http://gcc.gnu.org/faq.html

or here:

http://www.jamesd.demon.co.uk/csc/faq.html

-Howard



fvisibility-inlines-hidden

2006-02-03 Thread Howard Hinnant

Hello,

Is there a document, or a discussion that someone can point me to  
which explains why fvisibility-inlines-hidden applies to member  
functions, but not non-member functions?


Thanks,
Howard



Re: fvisibility-inlines-hidden

2006-02-03 Thread Howard Hinnant

On Feb 3, 2006, at 11:22 AM, Benjamin Kosnik wrote:



Is there a document, or a discussion that someone can point me to  
which

explains why fvisibility-inlines-hidden applies to member functions,
but not non-member functions?


AFAICT, there is very little documentation for any of the visibility
stuff. There is a web page referenced as "documentation", the pointer
to which you can find in the GCC-4.0.0 release notes.

There's been a lot of discussion in bugzilla about these features, but
little else.

-benjamin


Thanks Benjamin.  These are the docs I can find:

http://gcc.gnu.org/wiki/Visibility
http://gcc.gnu.org/onlinedocs/gcc/C_002b_002b-Dialect- 
Options.html#C_002b_002b-Dialect-Options


The two are contradictory towards the treatment of non-member inline  
functions.  I believe the first document is the one that correctly  
describes today's behavior.


I'm unable to find a bugzilla conversation which addresses this subject.

Let me rephrase:  It seems to me that fvisibility-inlines-hidden  
should apply to all inline functions (both member and non-member).   
Does anyone have an argument for why it should not be this way?


-Howard



Re: Question about use of C++ copy constructor

2006-03-13 Thread Howard Hinnant

Also see CWG issue 391:

http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#391

which will make our behavior non-conforming in C++0X.

-Howard

On Mar 13, 2006, at 4:02 PM, David Fang wrote:


Hi,
Didn't see a reply yet, so I'll chime in.

The relevant text appears in gcc-3.4's release notes:
"When binding an rvalue of class type to a reference, the copy  
constructor

of the class must be accessible."

PR 12226 seems to be the mother bug related to this (many dupes).

Fang


foo.cc: In function ¡Ævoid foo(const B&)¡Ç:
foo.cc:3: error: ¡ÆB::B(const B&)¡Ç is private
foo.cc:13: error: within this context

I don't understand why, as I don't see the copy constructor being  
used

anywhere.  It seems to me this code should create a temporary for the
duration of the statement, and pass the temporary as a reference to
b.fn.  This code compiles with icc with no errors.

What is wrong with this code?

class B {
 private:
  B(const B&);
  void operator=(const B&);

 public:
  B();
  void fn(const B &other) const;
};

void foo (const B& b)
{
  b.fn(B());
}









Re: Some C++0x experiments

2006-06-10 Thread Howard Hinnant

On Jun 9, 2006, at 9:31 PM, Pedro Lamarão wrote:


Any feedback is welcome!


Thank you!

-Howard



Re: [cfe-dev] C++11: new builtin to allow constexpr to be applied to performance-critical functions

2012-10-20 Thread Howard Hinnant
On Oct 19, 2012, at 10:51 PM, Richard Smith  wrote:

> 
> On Fri, Oct 19, 2012 at 10:50 PM, Chandler Carruth  
> wrote:
> On Fri, Oct 19, 2012 at 10:04 PM, Richard Smith  wrote:
> [Crossposted to both GCC and Clang dev lists]
> 
> Hi,
> 
> One issue facing library authors wanting to use C++11's constexpr feature is 
> that the same implementation must be provided for both the case of function 
> invocation substitution and for execution at runtime. Due to the constraints 
> on constexpr function definitions, this can force an implementation of a 
> library function to be inefficient. To counteract this, I'd like to propose 
> the addition of a builtin:
> 
>   bool __builtin_constexpr_p()
> 
> This builtin would only be supported within constexpr function definitions. 
> If the containing function is undergoing function invocation substitution, it 
> returns true. Otherwise, it returns false. Hence we can implement library 
> functions with a pattern like:
> 
>   constexpr int constexpr_strncmp(const char *p, const char *q, size_t n) {
> return !n ? 0 : *p != *q ? *p - *q : !*p ? 0 : constexpr_strncmp(p+1, 
> q+1, n-1);
>   }
>   __attribute__((always_inline)) constexpr int my_strncmp(const char *p, 
> const char *q, size_t n) {
> return __builtin_constexpr_p() ? constexpr_strncmp(p, q, n) : strncmp(p, 
> q, n);
>   }
> 
> Does this seem reasonable?
> 
> Yes, especially the primary functionality. However, I have some concerns 
> about the interface. Let me hypothesize a different interface:
> 
> This stays the same...
> constexpr int constexpr_strncmp(const char *p, const char *q, size_t n) {
>   return !n ? 0 : *p != *q ? *p - *q : !*p ? 0 : constexpr_strncmp(p+1, q+1, 
> n-1);
> }
> 
> But here we do something different on the actual declaration:
> [[constexpr_alias(constexpr_strncmp)]]
> int strncmp(const char *p, const char *q, size_t n);
> 
> When parsing the *declaration* of this function, we lookup the function name 
> passed to constexpr_alias. We must find a constexpr function with an 
> identical signature. Then, at function invocation substitution of strncmp, we 
> instead substitute the body of constexpr_strncmp.
> 
> This seems more direct (no redirection in the code), and it also provides a 
> specific advantage of allowing this to be easily added to an existing 
> declaration in a declaration-only header file without impacting or changing 
> the name of the runtime executed body or definition.
> 
> I really like this approach.

I'd love to see this is in the pre-Bristol mailing with implementation 
experience to back it up. :-)  Nice job Richard and Chandler!

Howard