Communitygithub.com

Padrões de Codificação C++

Padrões de codificação C++ baseados nas Diretrizes Principais de C++ (isocpp.github.io). Use ao escrever, revisar ou refatorar código C++ para aplicar práticas modernas, seguras e idiomáticas.

O que é Padrões de Codificação C++?

Esta skill fornece padrões de codificação abrangentes para C++ moderno (C++17/20/23), baseados nas Diretrizes Principais de C++ (C++ Core Guidelines). Ela abrange princípios fundamentais como RAII, imutabilidade por padrão, segurança de tipos e expressão de intenção, e inclui regras detalhadas para funções, classes, gerenciamento de recursos, expressões, tratamento de erros, constantes e concorrência. A skill é útil para desenvolvedores que escrevem, revisam ou refatoram código C++, garantindo um código mais seguro, claro e consistente. Ela suporta plataformas como Claude Code, Cursor e Codex, e é fornecida como um arquivo SKILL.md que pode ser referenciado durante o desenvolvimento.

Funciona com~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/affaan-m/ECC/tree/main/skills/cpp-coding-standards

Perguntar na sua IA favorita

Abre um novo chat com esta habilidade de agente já pré-carregada.

Documentação

Padrões de Codificação C++ (Diretrizes Principais de C++)

Padrões de codificação abrangentes para C++ moderno (C++17/20/23) derivados das Diretrizes Principais de C++. Aplica segurança de tipos, segurança de recursos, imutabilidade e clareza.

Quando Usar

  • Escrevendo novo código C++ (classes, funções, modelos)
  • Revisando ou refatorando código C++ existente
  • Tomando decisões arquiteturais em projetos C++
  • Aplicando estilo consistente em uma base de código C++
  • Escolhendo entre recursos da linguagem (por exemplo, enum vs enum class, ponteiro bruto vs ponteiro inteligente)

Quando NÃO Usar

  • Projetos que não são C++
  • Bases de código C legadas que não podem adotar recursos modernos de C++
  • Contextos embarcados/bare-metal onde diretrizes específicas entram em conflito com restrições de hardware (adaptar seletivamente)

Princípios Transversais

Esses temas se repetem em todas as diretrizes e formam a base:

  1. RAII em todo lugar (P.8, R.1, E.6, CP.20): Vincule o tempo de vida do recurso ao tempo de vida do objeto
  2. Imutabilidade por padrão (P.10, Con.1-5, ES.25): Comece com const/constexpr; mutabilidade é a exceção
  3. Segurança de tipos (P.4, I.4, ES.46-49, Enum.3): Use o sistema de tipos para prevenir erros em tempo de compilação
  4. Expresse intenção (P.3, F.1, NL.1-2, T.10): Nomes, tipos e conceitos devem comunicar propósito
  5. Minimize a complexidade (F.2-3, ES.5, Per.4-5): Código simples é código correto
  6. Semântica de valor sobre semântica de ponteiro (C.10, R.3-5, F.20, CP.31): Prefira retornar por valor e objetos com escopo

Filosofia e Interfaces (P., I.)

Regras Principais

RegraResumo
P.1Expresse ideias diretamente no código
P.3Expresse intenção
P.4Idealmente, um programa deve ser estaticamente seguro quanto ao tipo
P.5Prefira verificação em tempo de compilação à verificação em tempo de execução
P.8Não vaze nenhum recurso
P.10Prefira dados imutáveis a dados mutáveis
I.1Torne as interfaces explícitas
I.2Evite variáveis globais não-const
I.4Torne as interfaces precisas e fortemente tipadas
I.11Nunca transfira propriedade por um ponteiro bruto ou referência
I.23Mantenha o número de argumentos de função baixo

FAÇA

// P.10 + I.4: Interface imutável e fortemente tipada
struct Temperature {
    double kelvin;
};

Temperature boil(const Temperature& water);

NÃO FAÇA

// Interface fraca: propriedade incerta, unidades incertas
double boil(double* temp);

// Variável global não-const
int g_counter = 0;  // Violação de I.2

Funções (F.*)

Regras Principais

RegraResumo
F.1Empacote operações significativas como funções cuidadosamente nomeadas
F.2Uma função deve realizar uma única operação lógica
F.3Mantenha as funções curtas e simples
F.4Se uma função pode ser avaliada em tempo de compilação, declare-a constexpr
F.6Se sua função não deve lançar exceções, declare-a noexcept
F.8Prefira funções puras
F.16Para parâmetros "de entrada", passe tipos baratos de copiar por valor e outros por const&
F.20Para valores "de saída", prefira valores de retorno a parâmetros de saída
F.21Para retornar múltiplos valores "de saída", prefira retornar uma struct
F.43Nunca retorne um ponteiro ou referência a um objeto local

Passagem de Parâmetros

// F.16: Tipos baratos por valor, outros por const&
void print(int x);                           // barato: por valor
void analyze(const std::string& data);       // caro: por const&
void transform(std::string s);               // sink: por valor (irá mover)

// F.20 + F.21: Valores de retorno, não parâmetros de saída
struct ParseResult {
    std::string token;
    int position;
};

ParseResult parse(std::string_view input);   // BOM: retorna struct

// RUIM: parâmetros de saída
void parse(std::string_view input,
           std::string& token, int& pos);    // evite isso

Funções Puras e constexpr

// F.4 + F.8: Pura, constexpr quando possível
constexpr int factorial(int n) noexcept {
    return (n <= 1) ? 1 : n * factorial(n - 1);
}

static_assert(factorial(5) == 120);

Anti-Padrões

  • Retornar T&& de funções (F.45)
  • Usar va_arg / variádicos ao estilo C (F.55)
  • Capturar por referência em lambdas passadas para outras threads (F.53)
  • Retornar const T que inibe a semântica de movimento (F.49)

Classes e Hierarquias de Classe (C.*)

Regras Principais

RegraResumo
C.2Use class se invariante existe; struct se os membros de dados variam independentemente
C.9Minimize a exposição de membros
C.20Se você pode evitar definir operações padrão, faça (Regra do Zero)
C.21Se você define ou =delete qualquer copy/move/destrutor, lide com todos (Regra dos Cinco)
C.35Destrutor de classe base: virtual público ou protegido não-virtual
C.41Um construtor deve criar um objeto completamente inicializado
C.46Declare construtores de argumento único como explicit
C.67Uma classe polimórfica deve suprimir copy/move público
C.128Funções virtuais: especifique exatamente um de virtual, override ou final

Regra do Zero

// C.20: Deixe o compilador gerar membros especiais
struct Employee {
    std::string name;
    std::string department;
    int id;
    // Nenhum destrutor, construtores de cópia/movimento ou operadores de atribuição necessários
};

Regra dos Cinco

// C.21: Se você precisa gerenciar um recurso, defina todos os cinco
class Buffer {
public:
    explicit Buffer(std::size_t size)
        : data_(std::make_unique<char[]>(size)), size_(size) {}

    ~Buffer() = default;

    Buffer(const Buffer& other)
        : data_(std::make_unique<char[]>(other.size_)), size_(other.size_) {
        std::copy_n(other.data_.get(), size_, data_.get());
    }

    Buffer& operator=(const Buffer& other) {
        if (this != &other) {
            auto new_data = std::make_unique<char[]>(other.size_);
            std::copy_n(other.data_.get(), other.size_, new_data.get());
            data_ = std::move(new_data);
            size_ = other.size_;
        }
        return *this;
    }

    Buffer(Buffer&&) noexcept = default;
    Buffer& operator=(Buffer&&) noexcept = default;

private:
    std::unique_ptr<char[]> data_;
    std::size_t size_;
};

Hierarquia de Classe

// C.35 + C.128: Destrutor virtual, use override
class Shape {
public:
    virtual ~Shape() = default;
    virtual double area() const = 0;  // C.121: interface pura
};

class Circle : public Shape {
public:
    explicit Circle(double r) : radius_(r) {}
    double area() const override { return 3.14159 * radius_ * radius_; }

private:
    double radius_;
};

Anti-Padrões

  • Chamar funções virtuais em construtores/destrutores (C.82)
  • Usar memset/memcpy em tipos não triviais (C.90)
  • Fornecer argumentos padrão diferentes para função virtual e sobrescrita (C.140)
  • Tornar membros de dados const ou referências, o que suprime movimento/cópia (C.12)

Gerenciamento de Recursos (R.*)

Regras Principais

RegraResumo
R.1Gerencie recursos automaticamente usando RAII
R.3Um ponteiro bruto (T*) não possui
R.5Prefira objetos com escopo; não aloque no heap desnecessariamente
R.10Evite malloc()/free()
R.11Evite chamar new e delete explicitamente
R.20Use unique_ptr ou shared_ptr para representar propriedade
R.21Prefira unique_ptr a shared_ptr a menos que esteja compartilhando a propriedade
R.22Use make_shared() para criar shared_ptrs

Uso de Ponteiros Inteligentes

// R.11 + R.20 + R.21: RAII com ponteiros inteligentes
auto widget = std::make_unique<Widget>("config");  // propriedade única
auto cache  = std::make_shared<Cache>(1024);        // propriedade compartilhada

// R.3: Ponteiro bruto = observador não proprietário
void render(const Widget* w) {  // NÃO possui w
    if (w) w->draw();
}

render(widget.get());

Padrão RAII

// R.1: Aquisição de recurso é inicialização
class FileHandle {
public:
    explicit FileHandle(const std::string& path)
        : handle_(std::fopen(path.c_str(), "r")) {
        if (!handle_) throw std::runtime_error("Falha ao abrir: " + path);
    }

    ~FileHandle() {
        if (handle_) std::fclose(handle_);
    }

    FileHandle(const FileHandle&) = delete;
    FileHandle& operator=(const FileHandle&) = delete;
    FileHandle(FileHandle&& other) noexcept
        : handle_(std::exchange(other.handle_, nullptr)) {}
    FileHandle& operator=(FileHandle&& other) noexcept {
        if (this != &other) {
            if (handle_) std::fclose(handle_);
            handle_ = std::exchange(other.handle_, nullptr);
        }
        return *this;
    }

private:
    std::FILE* handle_;
};

Anti-Padrões

  • new/delete puros (R.11)
  • malloc()/free() em código C++ (R.10)
  • Múltiplas alocações de recurso em uma única expressão (R.13 -- risco de segurança de exceção)
  • shared_ptr onde unique_ptr é suficiente (R.21)

Expressões e Declarações (ES.*)

Regras Principais

RegraResumo
ES.5Mantenha os escopos pequenos
ES.20Sempre inicialize um objeto
ES.23Prefira sintaxe de inicializador {}
ES.25Declare objetos const ou constexpr a menos que a modificação seja pretendida
ES.28Use lambdas para inicialização complexa de variáveis const
ES.45Evite constantes mágicas; use constantes simbólicas
ES.46Evite conversões aritméticas de estreitamento/com perda
ES.47Use nullptr em vez de 0 ou NULL
ES.48Evite casts
ES.50Não remova const com cast

Inicialização

// ES.20 + ES.23 + ES.25: Sempre inicialize, prefira {}, padrão para const
const int max_retries{3};
const std::string name{"widget"};
const std::vector<int> primes{2, 3, 5, 7, 11};

// ES.28: Lambda para inicialização const complexa
const auto config = [&] {
    Config c;
    c.timeout = std::chrono::seconds{30};
    c.retries = max_retries;
    c.verbose = debug_mode;
    return c;
}();

Anti-Padrões

  • Variáveis não inicializadas (ES.20)
  • Usar 0 ou NULL como ponteiro (ES.47 -- use nullptr)
  • Casts ao estilo C (ES.48 -- use static_cast, const_cast, etc.)
  • Remover const com cast (ES.50)
  • Números mágicos sem constantes nomeadas (ES.45)
  • Misturar aritmética com e sem sinal (ES.100)
  • Reutilizar nomes em escopos aninhados (ES.12)

Tratamento de Erros (E.*)

Regras Principais

RegraResumo
E.1Desenvolva uma estratégia de tratamento de erros no início do design
E.2Lance uma exceção para sinalizar que uma função não pode executar sua tarefa atribuída
E.6Use RAII para evitar vazamentos
E.12Use noexcept quando lançar é impossível ou inaceitável
E.14Use tipos definidos pelo usuário projetados para o propósito como exceções
E.15Lance por valor, capture por referência
E.16Destrutores, desalocação e swap nunca devem falhar
E.17Não tente capturar toda exceção em toda função

Hierarquia de Exceções

// E.14 + E.15: Tipos de exceção personalizados, lance por valor, capture por referência
class AppError : public std::runtime_error {
public:
    using std::runtime_error::runtime_error;
};

class NetworkError : public AppError {
public:
    NetworkError(const std::string& msg, int code)
        : AppError(msg), status_code(code) {}
    int status_code;
};

void fetch_data(const std::string& url) {
    // E.2: Lance para sinalizar falha
    throw NetworkError("conexão recusada", 503);
}

void run() {
    try {
        fetch_data("https://api.example.com");
    } catch (const NetworkError& e) {
        log_error(e.what(), e.status_code);
    } catch (const AppError& e) {
        log_error(e.what());
    }
    // E.17: Não capture tudo aqui -- deixe erros inesperados propagarem
}

Anti-Padrões

  • Lançar tipos embutidos como int ou literais de string (E.14)
  • Capturar por valor (risco de slicing) (E.15)
  • Blocos catch vazios que engolem erros silenciosamente
  • Usar exceções para controle de fluxo (E.3)
  • Tratamento de erros baseado em estado global como errno (E.28)

Constantes e Imutabilidade (Con.*)

Todas as Regras

RegraResumo
Con.1Por padrão, torne os objetos imutáveis
Con.2Por padrão, torne as funções membro const
Con.3Por padrão, passe ponteiros e referências para const
Con.4Use const para valores que não mudam após a construção
Con.5Use constexpr para valores computáveis em tempo de compilação
// Con.1 a Con.5: Imutabilidade por padrão
class Sensor {
public:
    explicit Sensor(std::string id) : id_(std::move(id)) {}

    // Con.2: funções membro const por padrão
    const std::string& id() const { return id_; }
    double last_reading() const { return reading_; }

    // Apenas não-const quando a mutação é necessária
    void record(double value) { reading_ = value; }

private:
    const std::string id_;  // Con.4: nunca muda após a construção
    double reading_{0.0};
};

// Con.3: Passe por referência const
void display(const Sensor& s) {
    std::cout << s.id() << ": " << s.last_reading() << '\n';
}

// Con.5: Constantes de tempo de compilação
constexpr double PI = 3.14159265358979;
constexpr int MAX_SENSORS = 256;

Concorrência e Paralelismo (CP.*)

Regras Principais

RegraResumo
CP.2Evite condições de corrida de dados
CP.3Minimize o compartilhamento explícito de dados graváveis
CP.4Pense em termos de tarefas, em vez de threads
CP.8Não use volatile para sincronização
CP.20Use RAII, nunca lock()/unlock() puro
CP.21Use std::scoped_lock para adquirir múltiplos mutexes
CP.22Nunca chame código desconhecido enquanto segura um lock
CP.42Não espere sem uma condição
CP.44Lembre-se de nomear seus lock_guards e unique_locks
CP.100Não use programação livre de locks a menos que seja absolutamente necessário

Bloqueio Seguro

// CP.20 + CP.44: RAII locks, sempre nomeados
class ThreadSafeQueue {
public:
    void push(int value) {
        std::scoped_lock lock(mutex_);  // CP.21 + CP.44: Nomeado!
        queue_.push(value);
    }

    std::optional<int> pop() {
        std::scoped_lock lock(mutex_);
        if (queue_.empty()) return std::nullopt;
        int val = queue_.front();
        queue_.pop();
        return val;
    }

private:
    std::queue<int> queue_;
    std::mutex mutex_;
};

Esta Skill Aplica

  • Todos os padrões C++ Core Guidelines mencionados
  • RAII, imutabilidade, segurança de tipos
  • Regras de funções, classes, gerenciamento de recursos, erros e concorrência
  • Anti-padrões para evitar armadilhas comuns

Individual skills in this repo

This repo contains 20 individual skills — each has its own dedicated page.

accessibility

Design, implement, and audit inclusive digital products using WCAG 2.2 Level AA. Use when building or auditing UI that must meet WCAG 2.2 Level AA, or when reviewing a change for keyboard, contrast, or screen-reader support.

affaan-m/content-engine

Create platform-native content systems for X, LinkedIn, TikTok, YouTube, newsletters, and repurposed multi-platform campaigns. Use when the user wants social posts, threads, scripts, content calendars, or one source asset adapted cleanly across platforms.

affaan-m/ECC

Multi-platform content distribution across X, LinkedIn, Threads, and Bluesky. Adapts content per platform using content-engine patterns. Never posts identical content cross-platform. Use when the user wants to distribute content across social platforms.

affaan-m/fal-ai-media

Unified media generation via fal.ai MCP — image, video, and audio. Covers text-to-image (Nano Banana), text/image-to-video (Seedance, Kling, Veo 3), text-to-speech (CSM-1B), and video-to-audio (ThinkSound). Use when the user wants to generate images, videos, or audio with AI.

affaan-m/manim-video

日本語翻訳:このファイルは manim-video 用の日本語翻訳が必要です

affaan-m/remotion-video-creation

Remotion のベストプラクティス - React で動画を作成する。3D、アニメーション、音声、字幕、チャート、トランジションなどをカバーするドメイン固有の29のルール。

affaan-m/video-editing

AI-assisted video editing workflows for cutting, structuring, and augmenting real footage. Covers the full pipeline from raw capture through FFmpeg, Remotion, ElevenLabs, fal.ai, and final polish in Descript or CapCut. Use when the user wants to edit video, cut footage, create vlogs, or build video content.

agent-architecture-audit

Full-stack diagnostic for agent and LLM applications. Audits the 12-layer agent stack for wrapper regression, memory pollution, tool discipline failures, hidden repair loops, and rendering corruption. Produces severity-ranked findings with code-first fixes. Essential for developers building agent applications, autonomous loops, or any LLM-powered feature. Use when an agent or LLM feature misbehaves and the failing layer is unknown, or before shipping an agent stack.

agent-eval

Head-to-head comparison of coding agents (Claude Code, Aider, Codex, etc.) on custom tasks with pass rate, cost, time, and consistency metrics. Use when choosing between coding agents, or when a change to an agent setup needs measured pass rate, cost, and time rather than an impression.

agent-harness-construction

Design and optimize AI agent action spaces, tool definitions, and observation formatting for higher completion rates. Use when defining or revising an agent

agentic-engineering

Operate as an agentic engineer using eval-first execution, decomposition, and cost-aware model routing. Use when planning or executing engineering work that agents will carry out end to end.

agentic-os

Build persistent multi-agent operating systems on Claude Code. Covers kernel architecture, specialist agents, slash commands, file-based memory, scheduled automation, and state management without external databases. Use when building a persistent multi-agent system on Claude Code with its own memory, commands, and scheduling.

agent-introspection-debugging

Structured self-debugging workflow for AI agent failures using capture, diagnosis, contained recovery, and introspection reports. Use when an agent run fails and you need a reproducible diagnosis instead of a retry.

agent-payment-x402

Add x402 payment execution to AI agents with per-task budgets, spending controls, and non-custodial wallets. Supports Base through agentwallet-sdk and X Layer through OKX Payments / OKX Agent Payments Protocol. Use when an agent must pay for something itself and needs per-task budgets, spending controls, and a non-custodial wallet.

agent-self-evaluation

Use after completing any non-trivial task. The agent self-rates its output on 5 axes — accuracy, completeness, clarity, actionability, conciseness — with concrete evidence per criterion. Produces a structured 1-5 scorecard with specific improvement suggestions.

agent-sort

Build an evidence-backed ECC install plan for a specific repo by sorting skills, commands, rules, hooks, and extras into DAILY vs LIBRARY buckets using parallel repo-aware review passes. Use when ECC should be trimmed to what a project actually needs instead of loading the full bundle.

ai-first-engineering

Engineering operating model for teams where AI agents generate a large share of implementation output. Use when setting team process, review gates, or ownership rules for a codebase largely written by agents.

ai-regression-testing

Regression testing strategies for AI-assisted development. Sandbox-mode API testing without database dependencies, automated bug-check workflows, and patterns to catch AI blind spots where the same model writes and reviews code. Use when adding regression coverage to AI-assisted code, or when the same model both wrote and reviewed a change.

android-clean-architecture

Clean Architecture patterns for Android and Kotlin Multiplatform projects — module structure, dependency rules, UseCases, Repositories, and data layer patterns. Use when structuring modules, layers, or data flow in an Android or KMP project.

angular-developer

Generates Angular code and provides architectural guidance. Trigger when creating projects, components, or services, or for best practices on reactivity (signals, linkedSignal, resource), forms, dependency injection, routing, SSR, accessibility (ARIA), animations, styling (component styles, Tailwind CSS), testing, or CLI tooling.

Habilidades Relacionadas