Usar const corretamente em C e C++
Nesta lição, você vai usar a palavra-chave const para declarar dados somente leitura e diferenciar os usos de const com ponteiros.
Introdução
A palavra-chave const permite que uma função prometa não alterar os dados que recebe. Se alguém modificar sem querer um dado marcado como const, o compilador acusa o erro na hora. Isso deixa o código mais seguro e facilita para quem lê saber quais funções podem alterar dados.
Pontos importantes
- Um ponteiro só deve apontar para um objeto que ainda existe, do tipo certo, ou ser nulo.
- Cada área de memória alocada deve ser liberada exatamente uma vez.
- Deixe claro qual função é dona da memória (ownership) e quais dados são apenas lidos (const).
Exemplos de código C e C++
#include <stdio.h>
int sum(const int *values, size_t count) {
int total = 0;
for (size_t i = 0; i < count; ++i) total += values[i];
return total;
}
int main(void) {
const int values[] = {2, 4, 6};
printf("%d\n", sum(values, 3));
return 0;
}
12
#include <array>
#include <iostream>
int sum(const std::array<int, 3>& values) {
int total = 0;
for (int value : values) total += value;
return total;
}
int main() {
const std::array values{2, 4, 6};
std::cout << sum(values) << '\n';
}
12
Comparação entre C e C++
O parâmetro const int *values indica que a função sum só lê os elementos do array, sem alterá-los. Leia a declaração a partir do nome da variável: um ponteiro para dado const (const int *) protege o valor apontado, enquanto um ponteiro const (int * const) não pode apontar para outro endereço. C++ também tem funções-membro const, que prometem não alterar o estado do objeto.
A posse e a liberação da memória ficam totalmente por conta do programador.
Contêineres e RAII liberam os recursos automaticamente quando o objeto chega ao fim da vida.
Exercícios práticos
Execute as duas versões e depois mude o código para observar a diferença de segurança que cada linguagem oferece.
- Teste ponteiros nulos e falhas na alocação de memória.
- Execute o programa com AddressSanitizer e UndefinedBehaviorSanitizer para encontrar erros de memória.
- Anote claramente qual ponteiro é dono da memória e qual só serve para leitura.