This is the mail archive of the
mailing list for the GCC project.
Re: why GCC does implicit promotion to unsigned char?
On 27/01/2012 10:56, Richard Guenther wrote:
On Fri, Jan 27, 2012 at 10:40 AM, David Brown<firstname.lastname@example.org> wrote:
On 27/01/2012 10:02, Richard Guenther wrote:
On Thu, Jan 26, 2012 at 4:58 PM, David Brown<email@example.com>
On 26/01/2012 12:53, Konstantin Vladimirov wrote:
If I know what I am doing, and my code itself guarantees, that there
will be no overflows and UB here, can I switch off this signed char to
unsigned char expansion in favor of signed char to signed int
The big question here is why you are using an unqualified "char" for
arithmetic in the first place. The signedness of plain "char" varies by
target (some default to signed, some to unsigned) and by compiler flags.
you want to write code that uses signed chars, use "signed char". Or even
better, use<stdint.h> type "int8_t".
However, as has been pointed out, the problem is that signed arithmetic
doesn't wrap - it must be turned into unsigned arithmetic to make it
An alternative is to tell gcc that signed arithmetic is 2's compliment
wraps, by using the "-fwrapv" flag or "int8_t char sum_A_B(void)
__attribute__((optimize("wrapv")));" on the specific function.
Note that semantic changing optimize attributes do not work reliably.
Is there any more information about that somewhere? Certainly I expect
there to be issues when trying to turn on and off options like
"-fshort-enums" or "-freg-struct-return" - just as you can expect problems
linking modules that have been compiled with different flags like that. But
others like "-fwrapv", "-fargument-alias", or "-finstrument-functions" can
logically be applied to a single function. If there are problems with
changing these (with attributes or pragmas), then perhaps they should be
disabled, or the potential problems documented in the manual?
Well, the implementation is simply a bit naiive in accepting all options
and not all code is prepared to handle functions which differ in optimization
options. For example inlining happily will inline a -fwrapv function into
a -fno-wrapv function and later assume the inlined copy does have -fno-wrapv
semantics. The safe implementation here would have been to disallow
any inlining between functions that have any optimize attribute/pragma,
but that of course would defeat most of its use.
That said, using the attribute for debugging might be of help, but I would
not rely on it in any way.
That makes a lot of sense - thanks for the explanation. I had naively
been thinking that it should be safe to change "-fwrapv" for a function
- but inlining parts of other functions with different "-fwrapv"
settings would make things a lot more complicated.
Using a pragma to set -fwrapv at the start of a C file (before any
#include's that contained inline functions) would presumably be safe,
acting just the command line switch.
On the other hand, LTO might cause trouble there too...
For my own use, I would always put a flag like that in the makefile, and
almost always apply it globally to all files in the program - but not
everyone works like that, and it's nice to know the possibilities and