5

Background

By default signed overflow is undefined behaviour.

My understanding of gcc (based on https://gcc.gnu.org/onlinedocs/gcc/Code-Gen-Options.html and What does -fwrapv do?) was that using -fwrapv made gcc treat signed overflow as being well defined behaviour.

However, comments on another question seem to say that signed overflow is still undefined behaviour even when this flag is on.

Question

Is signed overflow well defined in gcc with -fwrapv? If not, then what is the purpose of -fwrapv?

Andrew Henle
  • 32,625
  • 3
  • 24
  • 56
Peter de Rivaz
  • 33,126
  • 4
  • 46
  • 75
  • When you run the program in your other question, does it go into an infinite loop or stop when`i+1` wraps around? – Barmar Mar 01 '19 at 23:04
  • If it stops, then I think it does what you expected. – Barmar Mar 01 '19 at 23:05
  • 1
    @Barmar Yes, the program always stops if I use -fwrapv. – Peter de Rivaz Mar 01 '19 at 23:11
  • Yes, it tells the compiler that signed overflow has predictable behavior. Like it does on the machine you compile your program on. Most important benefit is *not* to make your program work better, unintended overflow is always a very ratty logical problem. Benefit is to the optimizer, it is now allowed to pre-compute the result of an expression and take the result without worry that it might be different on the target architecture. – Hans Passant Mar 01 '19 at 23:17
  • 1
    @HansPassant Although I agree with what you say, in my particular case I am trying to use a program to simulate hardware (including wrap around of signed arithmetic) so I wanted to check that it is legal to use -fwrapv in this way – Peter de Rivaz Mar 01 '19 at 23:27

1 Answers1

6

Given the GCC documentation says:

-fwrapv

This option instructs the compiler to assume that signed arithmetic overflow of addition, subtraction and multiplication wraps around using twos-complement representation.

I'd characterize that as an implementation-specific extension that provides clearly defined behavior for what otherwise would be undefined behavior in standard C - if and only if the underlying hardware behaves that way.

Pedantically, I'd say it's still undefined behavior by the C standard, but you're instructing the compiler to act in a specific, non-portable but predictable manner.

Community
  • 1
  • 1
Andrew Henle
  • 32,625
  • 3
  • 24
  • 56
  • Thanks, so in particular would you consider it on-topic to ask questions on this site that rely on -fwrapv being used? (From the comments on the other question I got the impression that considered any question involved signed overflow was futile even when this flag was being used) – Peter de Rivaz Mar 01 '19 at 23:14
  • 1
    @PeterdeRivaz I think the comment saying you don't understand what it does was simply wrong. And the other comments may not have noticed that you were using `-fwrapv`. You should probably have made that more prominent in the question. – Barmar Mar 01 '19 at 23:17
  • @Barmar : Thanks - I wonder whether to edit the other question, but I suspect the comments now make it clear anyway. – Peter de Rivaz Mar 01 '19 at 23:24
  • 7
    Pedantically, there is not a category of behaviour called "undefined behaviour". The standard cannot mandate undefined behaviour because undefined behaviour is precisely a situation in which the standard mandates nothing. It is intentionally silent. It does not forbid anything, including a reproducible result. So an implementation can define a behaviour without contradicting the standard. – rici Mar 01 '19 at 23:25
  • @rici Thank you. I think that's what I was trying to say. You said it much better than I did. – Andrew Henle Mar 01 '19 at 23:34
  • 2
    Note that with this good answer some `signed overflow` remains UB as in `INT_MIN/-1`. – chux - Reinstate Monica Mar 02 '19 at 04:40
  • @rici: Indeed, one of the purposes of characterizing certain actions as invoking Undefined Behavior is to allow implementations to, as a form of "conforming language extension", define the behavior in useful ways not limited by the Committee's imagination. The only situations where a Committee's choice between IDB and UB was expected to matter were those where the cost of offering any sort of behavioral guarantee would exceed any possible value, and in most such cases leaving things as UB would make sense *even if 99% of implementations could offer useful guarantees at zero cost*. – supercat Jan 27 '21 at 17:21
  • Do you mean "if and only if the hardware works that way", or do you mean "for the addition, subtraction, multiplication, and left-shift operators, but not necessarily for the division or remainder operators?" There are platforms where `long1 = int1*int2;` could be processed more efficiently by directly computing a long-sized result than by sign-extending an `int`. Would `-fwrapv` not imply sign extension in such cases? – supercat Jan 27 '21 at 17:42