Skip to content

IntSub

Description

Generic subtraction convenience macro. Dispatches on the type of b to the matching IntSub* overload.

Parameters

Name Direction Description
result out Destination for the difference
a in Left operand
b in Right operand (Int, pointer, u64, or i64 compatible type)

Usage example (from documentation)

  bool ok = IntSub(&diff, &value, 1u);

Success

Returns true; *result holds a - b.

Failure

Returns false if an intermediate allocation fails; *result is unchanged.

Usage example (Cross-references)

Usage examples (Cross-references)
    
    bool test_int_sub(void) {
        WriteFmt("Testing IntSub\n");
    
        DefaultAllocator alloc = DefaultAllocatorInit();
        Int result_value = IntInit(&alloc.base);
    
        bool result = IntSub(&result_value, &a, &b);
        result      = result && (IntToU64(&result_value) == 255);
    
    bool test_int_sub_generic(void) {
        WriteFmt("Testing IntSub generic dispatch\n");
    
        DefaultAllocator alloc = DefaultAllocatorInit();
        Str text         = StrInit(&alloc.base);
    
        bool result = IntSub(&result_value, &base, &rhs);
        result      = result && (IntToU64(&result_value) == 38);
        result      = result && (IntToU64(&result_value) == 38);
    
        result = result && IntSub(&result_value, &base, 2u);
        result = result && (IntToU64(&result_value) == 38);
        result = result && (IntToU64(&result_value) == 38);
    
        result = result && IntSub(&result_value, &base, -2);
        result = result && (IntToU64(&result_value) == 42);
        result = result && (IntToU64(&result_value) == 42);
    
        result = result && IntSub(&result_value, &huge, 90);
        text   = IntToStr(&result_value);
        result = result && (ZstrCompare(StrBegin(&text), "12345678901234567800") == 0);
        result = result && (ZstrCompare(StrBegin(&text), "12345678901234567800") == 0);
    
        result = result && !IntSub(&preserved, &base, 50);
        result = result && (IntToU64(&preserved) == 99);
    
    bool test_int_sub_underflow_preserves_result(void) {
        WriteFmt("Testing IntSub underflow handling\n");
    
        DefaultAllocator alloc = DefaultAllocatorInit();
        Int result_value = IntFrom(99, &alloc.base);
    
        bool result = !IntSub(&result_value, &a, &b);
        result      = result && (IntToU64(&result_value) == 99);
    // caller-observable difference diverges (3 vs 5).
    bool test_m15_sub_borrow_propagates(void) {
        WriteFmt("Testing IntSub borrow propagation across bits\n");
    
        DefaultAllocator alloc = DefaultAllocatorInit();
        Int result_value = IntInit(&alloc.base);
    
        bool ok = IntSub(&result_value, &a, &b);
        ok      = ok && (IntToU64(&result_value) == 3);
    // ValidateInt on both, so only the result validation is uniquely observable.)
    bool test_m15_sub_null_result(void) {
        WriteFmt("Testing IntSub NULL result handling\n");
    
        DefaultAllocator alloc = DefaultAllocatorInit();
        Int r = IntFrom(7u, a);
    
        bool ok = IntSub(&r, &x, &y);
        ok      = ok && IntToU64(&r) == 17u;
        Int r = IntFrom(7u, a);
    
        bool ok = IntSub(&r, &x, 250u); // int_sub_u64 frees rhs on success (1187)
        ok      = ok && IntToU64(&r) == 750u;
Last updated on