Do C++ signed types have modulo semantics?

Nathan Sidwell nathan@codesourcery.com
Mon Jun 27 14:36:00 GMT 2005


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
nathan@codesourcery.com    ::     http://www.planetfall.pwp.blueyonder.co.uk



More information about the Gcc mailing list