---
title: "@addWithOverflow em Zig — Referência e Exemplos"
url: "https://ziglang.com.br/builtins/@addwithoverflow-em-zig-refer%C3%AAncia-e-exemplos/"
markdown_url: "https://ziglang.com.br/builtins/@addwithoverflow-em-zig-refer%C3%AAncia-e-exemplos.MD"
description: "Referência completa do @addWithOverflow em Zig. Adição com detecção de overflow retornando resultado e flag. Exemplos práticos pt-BR."
date: "2026-02-21"
author: "Zig Brasil"
---

# @addWithOverflow em Zig — Referência e Exemplos

Referência completa do @addWithOverflow em Zig. Adição com detecção de overflow retornando resultado e flag. Exemplos práticos pt-BR.


# @addWithOverflow em Zig

O `@addWithOverflow` realiza uma adição e indica se houve **overflow**. Retorna uma tupla com o resultado (possivelmente truncado) e um bit de overflow. Isso permite tratar overflow explicitamente em vez de causar panic (modo safe) ou undefined behavior (modo unsafe).

## Sintaxe

```zig
@addWithOverflow(a: T, b: T) struct { T, u1 }
```

## Parâmetros

- **a** (`T`): Primeiro operando (tipo inteiro).
- **b** (`T`): Segundo operando (mesmo tipo inteiro).

## Valor de retorno

Retorna uma tupla `struct { T, u1 }`:
- **[0]** (`T`): Resultado da adição (truncado ao tamanho do tipo se houve overflow).
- **[1]** (`u1`): `1` se houve overflow, `0` caso contrário.

## Exemplos práticos

### Exemplo 1: Detecção básica de overflow

```zig
const std = @import("std");

pub fn main() void {
    // Sem overflow
    const r1 = @addWithOverflow(@as(u8, 100), @as(u8, 50));
    std.debug.print("100 + 50 = {} (overflow: {})\n", .{ r1[0], r1[1] });
    // 100 + 50 = 150 (overflow: 0)

    // Com overflow: 200 + 100 = 300, mas u8 vai até 255
    const r2 = @addWithOverflow(@as(u8, 200), @as(u8, 100));
    std.debug.print("200 + 100 = {} (overflow: {})\n", .{ r2[0], r2[1] });
    // 200 + 100 = 44 (overflow: 1)  — 300 mod 256 = 44
}
```

### Exemplo 2: Adição segura com tratamento de erro

```zig
const std = @import("std");

fn somaSegura(a: u32, b: u32) !u32 {
    const resultado = @addWithOverflow(a, b);
    if (resultado[1] != 0) {
        return error.Overflow;
    }
    return resultado[0];
}

pub fn main() void {
    const a = somaSegura(1_000_000, 2_000_000) catch |err| {
        std.debug.print("Erro: {}\n", .{err});
        return;
    };
    std.debug.print("Resultado: {}\n", .{a}); // 3000000

    const b = somaSegura(std.math.maxInt(u32), 1) catch |err| {
        std.debug.print("Erro: {s}\n", .{@errorName(err)}); // Overflow
        return;
    };
    _ = b;
}
```

### Exemplo 3: Acumulador com detecção de limite

```zig
const std = @import("std");

fn somarArray(valores: []const u16) struct { soma: u16, overflow: bool } {
    var total: u16 = 0;
    var teve_overflow = false;

    for (valores) |v| {
        const r = @addWithOverflow(total, v);
        total = r[0];
        if (r[1] != 0) teve_overflow = true;
    }

    return .{ .soma = total, .overflow = teve_overflow };
}

pub fn main() void {
    const dados = [_]u16{ 10000, 20000, 30000, 10000 };
    const resultado = somarArray(&dados);

    if (resultado.overflow) {
        std.debug.print("AVISO: overflow detectado!\n", .{});
    }
    std.debug.print("Soma (possivelmente truncada): {}\n", .{resultado.soma});
}
```

## Casos de uso comuns

1. **Aritmética segura**: Detectar overflow sem causar panic.
2. **Criptografia**: Operações que precisam de wrap-around explícito.
3. **Validação de entrada**: Verificar se somas de valores do usuário excedem limites.
4. **Contadores**: Detectar quando um contador atinge o valor máximo.

## Comportamento por modo de compilação

O `@addWithOverflow` se comporta de forma **idêntica em todos os modos** (Debug, ReleaseSafe, ReleaseFast, ReleaseSmall): sempre retorna o resultado truncado e o bit de overflow. Não há panic, não há undefined behavior.

Isso o diferencia do operador `+` simples:

| Modo | Operador `+` com overflow | `@addWithOverflow` |
|------|--------------------------|-------------------|
| Debug | panic em runtime | resultado + bit 1 |
| ReleaseSafe | panic em runtime | resultado + bit 1 |
| ReleaseFast | undefined behavior | resultado + bit 1 |
| ReleaseSmall | undefined behavior | resultado + bit 1 |

## Equivalente em C

Em C, detectar overflow de soma com segurança é mais verboso:

```c
#include <stdint.h>
#include <stdbool.h>

// Método 1: usando __builtin_add_overflow (GCC/Clang)
bool soma_segura_c(uint32_t a, uint32_t b, uint32_t *resultado) {
    return __builtin_add_overflow(a, b, resultado);
}

// Método 2: comparação manual
bool soma_segura_manual(uint32_t a, uint32_t b, uint32_t *resultado) {
    *resultado = a + b;
    return *resultado < a; // overflow se resultado menor que operando
}
```

Em Zig, `@addWithOverflow` é mais conciso e seguro por padrão.

## Erros comuns

**Ignorar o bit de overflow**: O retorno mais comum é usar apenas `r[0]` sem verificar `r[1]`. Isso derrota o propósito do builtin.

```zig
// ERRADO: ignora o overflow
const soma = @addWithOverflow(a, b)[0];

// CORRETO: verificar o overflow
const r = @addWithOverflow(a, b);
if (r[1] != 0) return error.Overflow;
const soma = r[0];
```

**Confundir com wrapping arithmetic**: Se você quer soma que wraps sem erro, use o operador `+%`:

```zig
const wrapped = a +% b; // wrap intencional, sem verificação
const checked = @addWithOverflow(a, b); // resultado + flag
```

## Perguntas Frequentes

**Por que o resultado é truncado e não zero/máximo em caso de overflow?**

O Zig retorna o resultado módulo 2^N (onde N é a largura do tipo) por consistência com a aritmética de inteiros e para permitir que o chamador decida o que fazer. Às vezes o valor truncado é útil (em hashing ou criptografia, por exemplo).

**Posso usar `@addWithOverflow` com tipos signed?**

Sim. O builtin funciona com `i8`, `i16`, `i32`, `i64`, etc. O overflow signed também é detectado corretamente — por exemplo, `@addWithOverflow(@as(i8, 127), @as(i8, 1))` retorna `{-128, 1}`.

**`@addWithOverflow` tem custo em performance?**

Em arquiteturas modernas (x86-64, ARM64), o compilador mapeia para instruções que definem a flag de carry/overflow automaticamente. O custo é geralmente nulo ou mínimo — uma instrução ADD seguida de leitura da flag.

## Builtins relacionados

- [@subWithOverflow](/builtins/sub-with-overflow/) — Subtração com detecção de overflow
- [@mulWithOverflow](/builtins/mul-with-overflow/) — Multiplicação com detecção de overflow
- [@shlExact](/builtins/shl-exact/) — Shift left exato
- [@min](/builtins/min/) / [@max](/builtins/max/) — Limitar valores

## Tutoriais relacionados

- [Aritmética em Zig](/tutoriais/aritmetica-zig/)
- [Sistema de Tipos do Zig](/tutoriais/tipos/)
- [Introdução ao Zig](/tutoriais/introducao-ao-zig/)
