home bbs files messages ]

Forums before death by AOL, social media and spammers... "We can't have nice things"

   comp.lang.c      Meh, in C you gotta define EVERYTHING      243,242 messages   

[   << oldest   |   < older   |   list   |   newer >   |   newest >>   ]

   Message 241,351 of 243,242   
   David Brown to pozz   
   Re: signed vs unsigned and gcc -Wsign-co   
   20 Oct 25 20:03:34   
   
   From: david.brown@hesbynett.no   
      
   On 20/10/2025 17:03, pozz wrote:   
   > After many years programming in C language, I'm always unsure if it is   
   > safer to use signed int or unsigned int.   
   >   
   > Of course there are situations where signed or unsigned is clearly   
   > better. For example, if the values could assume negative values, signed   
   > int is the only solution. If you are manipulating single bits (&, |, ^,   
   > <<, >>), unsigned ints are your friends.   
   >   
   > What about other situations? For example, what do you use for the "i"   
   > loop variable?   
   >   
   > I recently activated gcc -Wsign-conversion option on a codebase and   
   > received a lot of warnings. I started to fix them, usually expliciting   
   > casting. Is it the way or is it better to avoid the warning from the   
   > beginning, choosing the right signed or unsigned type?   
   >   
   >   
      
   Signed and unsigned types are equally safe.  If you are sure you are   
   within the ranges you know will work for the types you use, your code is   
   safe.  If you are not sure, you are unsafe.  It doesn't matter if an   
   overflow is undefined behaviour leading to a bug, or defined but   
   unexpected behaviour leading to a bug.  (Of course, if you are using the   
   defined wrapping behaviour of unsigned types in a way that you know is   
   correct for your program, then that is safe.  All overflows for signed   
   types are unsafe, as are all unexpected overflows of unsigned types.)   
      
   Signed types can be more efficient in some circumstances, as they obey a   
   number of useful mathematical rules that can be used for optimisation.   
   Unsigned types - of the size of "unsigned int" or bigger - obey   
   different mathematical identities that can occasionally be useful but   
   often hinder optimisations.   
      
   Beware assumptions about wrapping of unsigned types smaller than   
   "unsigned int" - these promote to "int", and arithmetic is then done   
   with "int" with UB overflow, before possibly being converted back to the   
   smaller unsigned integer type.   
      
   If your target has bigger registers than "int", sometimes code can be   
   surprisingly inefficient for "unsigned int".  If you have a 64-bit   
   target and have an expression like "array[i++];" in a loop, it can be   
   significantly less efficient if "i" is "unsigned int" because the   
   compiler must assume that "i++" might wrap.  If "i" is "int", or a   
   64-bit type (like "size_t" on such a target), there is no such issue.   
   (It is not uncommon that "int_fast32_t" or "uint_fast32_t" will be   
   faster than plain "int" or "unsigned int", because these will be 64-bit   
   on 64-bit targets.)   
      
   So very often, the efficient choice of type is "int" or "int_fastN_t"   
   for code that might be used on 64-bit platforms.  Size-explicit types   
   are the best choice if your code has to run on smaller platforms, so   
   that you can be sure your types are big enough.  But if the compiler can   
   determine the range of an unsigned variable (such as in a "for" loop   
   where the start and end cases are known at compile-time), then unsigned   
   types will be just as efficient.   
      
   Comparisons between signed and unsigned types do turn up regularly, and   
   sometimes casts are necessary if you want to enable warnings about these   
   and can't reasonably pick the signedness for the two sides of the   
   comparison.  It's a question of style and preference whether you want to   
   enable such warnings - most people do not, I think.   
      
   --- SoupGate-Win32 v1.05   
    * Origin: you cannot sedate... all the things you hate (1:229/2)   

[   << oldest   |   < older   |   list   |   newer >   |   newest >>   ]


(c) 1994,  bbs@darkrealms.ca