invalid character in source — Como Resolver em Zig
O Que Este Erro Significa
O erro invalid character in source ocorre quando o compilador Zig encontra um caractere no código-fonte que não é permitido fora de strings e comentários. Zig é rigoroso sobre quais caracteres são válidos no código-fonte: apenas ASCII imprimível (exceto certas exceções), newlines e tabs em contextos específicos. Caracteres Unicode fora de strings literais, caracteres de controle invisíveis e marcas BOM (Byte Order Mark) são rejeitados.
Causas Comuns
1. BOM (Byte Order Mark) no Início do Arquivo
Alguns editores (especialmente no Windows) adicionam um caractere BOM (U+FEFF) invisível no início de arquivos UTF-8:
// O arquivo começa com bytes invisíveis: EF BB BF
const std = @import("std"); // ERRO: invalid character
2. Caracteres Unicode em Identificadores
pub fn main() void {
const preço = 42; // ERRO: 'ç' não é ASCII válido em identificadores
_ = preço;
}
3. Aspas Inteligentes (Smart Quotes)
Copiando código de editores de texto ou páginas web, você pode acabar com aspas curvas:
pub fn main() void {
const nome = "Zig"; // ERRO: aspas curvas " " ao invés de retas " "
_ = nome;
}
4. Espaço Não-Quebrável (Non-Breaking Space)
O caractere U+00A0 (non-breaking space) se parece com um espaço normal, mas não é:
pub fn main() void {
const x = 42; // ERRO: espaço invisível errado entre 'const' e 'x'
_ = x;
}
5. Tab em Local Inadequado
Zig tem regras específicas sobre onde tabs são permitidos. O zig fmt converte tabs para espaços:
pub fn main() void {
const x = 42; // Tab para indentação — pode causar aviso
_ = x;
}
6. Caracteres de Controle Copiados Acidentalmente
pub fn main() void {
const x = 42; // Pode conter Ctrl+M (^M / \r) em arquivos do Windows
_ = x;
}
Como Corrigir
Solução 1: Remover BOM do Arquivo
No Linux/macOS:
# Verificar se o arquivo tem BOM
file src/main.zig
# Remover BOM
sed -i '1s/^\xEF\xBB\xBF//' src/main.zig
No VS Code: abra o arquivo, clique em “UTF-8 with BOM” no canto inferior direito e selecione “UTF-8” (sem BOM).
Solução 2: Usar Apenas ASCII em Identificadores
pub fn main() void {
const preco = 42; // Correto: 'preco' sem acentos
_ = preco;
}
Se precisar de texto com acentos, use strings:
const nome_display = "Preço"; // Unicode é permitido dentro de strings
Solução 3: Substituir Aspas Inteligentes
pub fn main() void {
const nome = "Zig"; // Correto: aspas retas
_ = nome;
}
Solução 4: Usar zig fmt
O formatador do Zig pode corrigir alguns desses problemas automaticamente:
zig fmt src/main.zig
Solução 5: Converter Fins de Linha
Converta \r\n (Windows) para \n (Unix):
# No Linux/macOS
dos2unix src/main.zig
# Ou com sed
sed -i 's/\r$//' src/main.zig
Solução 6: Reescrever o Arquivo
Se nada mais funcionar, crie um novo arquivo e copie apenas o texto visível:
# Copiar apenas caracteres ASCII imprimíveis + newlines
tr -cd '\11\12\15\40-\176' < src/main.zig > src/main_clean.zig
mv src/main_clean.zig src/main.zig
Como Prevenir
Configurar o Editor Corretamente
VS Code — adicione ao settings.json:
{
"files.encoding": "utf8",
"files.eol": "\n",
"editor.renderControlCharacters": true,
"files.trimTrailingWhitespace": true
}
Vim — adicione ao .vimrc:
set encoding=utf-8
set fileformat=unix
set list
Usar .editorconfig
Crie um arquivo .editorconfig no projeto:
[*.zig]
charset = utf-8
end_of_line = lf
indent_style = space
indent_size = 4
trim_trailing_whitespace = true
insert_final_newline = true
Verificar com xxd ou hexdump
Para encontrar caracteres invisíveis problemáticos:
xxd src/main.zig | head -5
# Procure por bytes fora do range 20-7E (exceto 0A e 0D)
Caracteres Válidos no Código-Fonte Zig
- Identificadores: letras ASCII (
a-z,A-Z), dígitos (0-9), underscore (_) - Strings: qualquer sequência de bytes UTF-8 válida
- Comentários: qualquer sequência de bytes UTF-8 válida
- Whitespace: espaço (
0x20), newline (0x0A)
Erros Relacionados
- expected expression — Expressão esperada pelo compilador
- expected ‘;’ — Ponto e vírgula faltando
- expected ‘}’ — Chave de fechamento faltando