Gabriel Dos Reis wrote:
But a compiler could define them to be modulo -- that is the whole
point. The paragraph does not say they don't "modulo".
of course it could do so, but then to be useful it should document it, and it
would be an extension.
| 18.2.1.2/57 claims is_modulo is true 'for signed types on most
| machines'. Such an assertion is false when optimizations rely the
| undefinedness of signed overflow. A DR should probably be filed
| (maybe one is, I'm not at all familiar with library DRs).
Well, undefined behaviour does not mean unconditional hell or evil.
It is just behaviour left up to the compiler to whatever it wants.
correct. However the std *itself* says in one place 'this is undefined' and in
another place 'this is usually modulo'. I find that confusing at best.
And all useful programs we write rely on undefined behaviour of one
sort or the other, starting with GCC. In the case of
They do? I thought they usually relied on implementation defined, documented
extensions or were part of the implementation. Now I'm sure you'll prove me
wrong in some way or other, but please stick to the point -- do real important
programs that must not break and cannot be changed rely on signed modulo behaviour?
When RTH helped cleanup the numeric_limits implementation in September
2002, he made a very good point (which I held to be true, since
obviously he is The Middle-end and Back-end Guy)
http://gcc.gnu.org/ml/libstdc++/2002-09/msg00207.html
thanks for that. I was under the impression that some of the loop optimizers
relied on the fact that iterating over a signed type did not do odd modulo
related things. Indeed this comment in loop.c concerning BIVs leads me to
believe we already fail to honor the is_modulo value
Note that treating the entire pseudo as a BIV will result in making
simple increments to any GIVs based on it. However, if the variable
overflows in its declared mode but not its promoted mode, the result will
be incorrect. This is acceptable if the variable is signed, since
overflows in such cases are undefined, but not if it is unsigned, since
those overflows are defined. So we only check for SIGN_EXTEND and
not ZERO_EXTEND.
Anyway, this doesn't answer Michael's question. He asked whether C and C++
differ in this regard. The answer is the standards are the same, and the
implementation is the same (because it is the same backend). So, if whatever
optimizations he is turning on change the behaviour rth cited, then limits
should change too.
I don't particularly care what behaviour is chosen, except that
1) C and C++ implementations should behave the same way
2) we should pick the behaviour that leads to better code generation in real
life.
3) if modulo behaviour is chosen, it should be well documented in a place more
prominant than type_traits<int>::is_modulo.
nathan
--
Nathan Sidwell :: http://www.codesourcery.com :: CodeSourcery LLC
[EMAIL PROTECTED] :: http://www.planetfall.pwp.blueyonder.co.uk