Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>C cares nothing about your algorithm, nor does it know whether your variables will underflow or not, nor does it know if the underflow is intentional or accidental. Under-/overflows for unsigned integers is well-defined behavior, so in this case the compiler will happily do what you tell it to: create an underflow.</p> <hr> <p>Some details:</p> <pre><code>unsigned int secondsLeft = (currentTickSeconds - prevTickSeconds ) ? currentTickSeconds - prevTickSeconds : 60 - prevTickSeconds + currentTickSeconds; </code></pre> <p>If we replace all variables in this expression with their corresponding types, we get:</p> <pre><code>unsigned int = (unsigned int - unsigned int) ? unsigned int - unsigned int : int - unsigned int + unsigned int; </code></pre> <p>All C cares about is its implicit type promotion rules. There are two such rules in this expression: regular balancing (<em>the usual arithmetic conversions</em>) and a special balancing rule for the ?: operator.</p> <p>The balancing rules state that if two integers of the same size are operands of an expression, and one of them is unsigned, the signed operand will get converted to an unsigned one.</p> <pre><code>unsigned int = (unsigned int - unsigned int) ? // no conversion needed unsigned int - unsigned int : // no conversion needed (int - unsigned int) // convert the int to unsigned int + unsigned int; // we get unsigned + unsigned, no conversion needed </code></pre> <p>And then the result is stored in an unsigned int.</p> <p>There is however a special (weird) rule in C, related to the conditional operator ?:. The 2nd operand and and the 3rd operand are balanced as if they were operators of the same expression. So if you have this case:</p> <pre><code>1 ? (signed int)x : (unsigned int)y; </code></pre> <p>then the result will always be unsigned int. This is because x and y are treated as if they were part of the same operation, even though y is never used in the code. This can create subtle bugs and it is reason enough to avoid the ?: operator entirely, in my opinion.</p>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    1. COIn which way is the rule for the ternary operator *"weird"* or even special? You have an operation and its type is the converted (or *"balanced"*) type of its operands (Ok, it's special in the sense that the first operand's type is rather ignored). Don't mistake the ternary operator for an `if`. It's an expression and needs a type. Using the type of the selected operand is impossible since that is not known until runtime, no matter if you can construct a special case where it **could** be known at compile time.
      singulars
    2. CO@ChristianRau Because C programmers use ?: as a replacement for if statements. But as shown, it doesn't behave like if-statements in terms of type promotions. There is never a dependency between the contents of if(){} and the contents of else{}. Anyway, the ?: is a superfluous feature of the language, it only exists to sate various fuzzy, subjective coding style opinions. Misguided programmers tend to use it for "optimization", but it will never result in faster code compared to if-statements. On the contrary, often slower code because of the forced balancing rule.
      singulars
    3. COWell, of course using a language feature you (not you, the *"C programmers"* referred to your comment) don't completely understand can be a cause for problems. That doesn't make the feature a bad one. Of course it's entirely for convenience and clarity (yes, a one-line conditional assignment is more concise **and** clearer), but neither do I want to write `i = i + 1` all the time, no matter if it's the exact same as `++i`. It's not for runtime optimization, but for programming, reading and thinking time optimization. Who thinks different is, well, indeed misguided, but that's not C's problem.
      singulars
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload