-
Notifications
You must be signed in to change notification settings - Fork 139
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Improve -fno-strict-overflow description #694
base: main
Are you sure you want to change the base?
Conversation
253f354
to
79d4dd9
Compare
|
||
#### Synopsis | ||
|
||
In C and C++ unsigned integers have long been defined as "wrapping around". However, for many years C and C++ have assumed that overflows do not occur in many other circumstances. Overflow when doing arithmetic with signed numbers is considered undefined by many versions of the official specifications, This approach also allows the compiler to assume strict pointer semantics: if adding an offset to a pointer does not produce a pointer to the same object. In practice, this means that important security checks written in the source code may be silently ignored when generating executable code. | ||
In C and C++ unsigned integers have long been defined as "wrapping around". However, C and C++ compilers, by default, assume that overflows do not occur in other circumstances. Overflow when doing arithmetic with signed numbers is considered undefined the language specifications. This allows the compiler to assume strict pointer semantics: if adding an offset to a pointer does not produce a pointer to the same object, the addition is undefined. In practice, this means that important security checks written in the source code may be silently ignored when generating executable code. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"undefined the language" -> "undefined in the language"
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed in e667c2f.
@@ -937,15 +937,18 @@ There are normally no significant performance implications. Null pointer checks | |||
|
|||
--- | |||
|
|||
### Integer overflow may occur | |||
### Define behavior for signed integer and pointer arithmetic overflows |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Some of these don't define behavior, they complain about it, right?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The options we cover here make signed-integers-arithmetic and pointer-arithmetic overflows either wrap-around or trap so I think it's justifiable to characterize that as defined behavior (as opposed to the default undefined behavior which allows for the optimizations that may case problems). We don't cover warnings here, so I'd be inclined to leave "defined" as it is.
|
||
#### When not to use? | ||
|
||
Standards-compliant C and C++ should not require any particular behavior for signed arithmetic overflows. Code which requires a specific behavior, such as a two's-complement representation becomes less portable in a very subtle way. Consequently, strictly standard-compliant C and C++ should not need the flags described in this section, and we recommend striving to write code that does not assume specific arithmetic overflow behavior. However, mistakes are inevitable and consequently we believe most code will benefit from `-fno-strict-overflow` or its alternatives. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are you sure? Let's check. Newer standards may require twos-complement.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Indeed you are right. In addition to C++20 which Gabriel pointed us to also C23 now requires two's complement representation for signed integers. Fixed in 203728f.
|
||
#### Performance implications | ||
|
||
Each of these options gives the compiler less freedom for optimizing the resulting machine code compared to the default `-fstrict-overflow` behavior. For example, under `-fstrict-overflow` semantics, expressions such as `i + 10 > i` will always be true for signed `i`, allowing the expression to be replaced at compile time with a constant value. As discussed above, if such expressions occur in condition checks the compiler may optimize away entire code paths when the expression can be evaluated at compile time. In contrast, under `-fno-strict-overflow` those expression must be evaluated at run-time in case of overflows that wrap around the value, thus preventing some optimizations. On the other hand, treating overflows as undefined behavior will only yield optimal behavior if the programmer can be certain the program will never inputs that cause overflows. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"will never inputs" -> "will never accept inputs"
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed in 203728f.
Add -ftrapv and -fsanitize=signed-integer-overflow as alternative option Signed-off-by: Thomas Nyman <[email protected]>
Signed-off-by: Thomas Nyman <[email protected]>
fc2d0ff
to
203728f
Compare
Improve
-fno-strict-overflow
description and document changes in GCC 8.5.Add
-ftrapv
and-fsanitize=signed-integer-overflow
as alternative options.Add missing "When not to use?", "Performance implications", and "Other considerations subsections"
Fixes #685