Of course not every CPU has a carry flag...
Of course not every CPU has a carry flag...
What if the architecture doesn't have a carry? Then the compiler has to generate one when needed.
What if the architecture has better ways to do the addition anyway? What if the architecture is only 8bit and even regular "int" adds take several instructions anyway, so it makes so sense opmimizing for 128bit adds?
C doesn't even mandate what happens in case of an integer overflow, it has no business exposing carry flags.
If I ever write a C tutorial I'll title it "How I learned to stop worrying and love the compiler".
EDIT: of course in this case you can't really "let the compiler handle it" if you care about bignum performances. The only solution here would be
a/ expose much more hardware state to the language, which as I've already stated doesn't sound very convenient or C-ish enough for me,
b/ modify the optimizer to better handle bignum code or
c/ use a bignum library and possibly make it part of the standard.
I wouldn't be opposed to a standard <bignum.h>, I think it would make some sense. In the meantime I just use gmp.h, it's faster than anything I could come up with anyway, asm or otherwise. Bignum is hard.
Adding two N-bit numbers produces N+1-bit result, and C gives you no direct means of accessing the full result. IMO, this is a language defect and has little to do with HW support. [This pertains also to multiplication: NxN bits -> 2N-bit result.]
If the hardware actually returns the full result, excellent; if no, the compiler has to synthesize code to compute it, if needed. Whether it's needed is inferrable by the code that follows, e.g., the type of the variable the result is assigned to.
IMO, inferring that only a partial result is used (e.g., carry is discarded) is much easier for the optimizer than inferring what some instruction sequence is supposed to do. (E.g., 4+ multiplications and few additions => single 32x32=>64 multiply.)
What is your point? If you want to do multiple precision arithmetic in assembly, then on the architectures which don't have a carry, you must indeed generate one, so what? If a language has some operations with carry, then it is up to the programmer to use them only when he needs them..
> C doesn't even mandate what happens in case of an integer overflow
That's for performance reasons, and I would say that it is the wrong default aka 'premature optimisation', a better language would have 'int' with overflow checks (which could be disabled by a compiler switch) and int_raw for the unsafe&fast behaviour.
I agree that the carry flag shouldn't be exposed directly, but the ability to express "add and check for overflow" would be useful and allow for these optimisations where the architecture supports it.
Edit: But if you want to exploit the processor to its fullest, go with assembly. The compiler is good, but proving optimisations is a hard problem, and complex, single-instruction-specific optimisations aren't going to take off any time soon.
From https://en.wikipedia.org/wiki/Status_register#CPU_architectu... those architectures put the carry result in a general-purpose register, but you still can't access the result in C.