Re: Gfortran and using C99 cbrt for X ** (1./3.)
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.)
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.)
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
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
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
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
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
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
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
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
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
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
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
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
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
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)?
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
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
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
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
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
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