=========================================
C é uma linguagem que bastante antiga e com uma comunidade bastante madura, em início de sua história ocorreram bastantes mudanças, mais notavelmente do C estilo K&R para o popular ANSI C. Essa linguagem é tão universalmente conhecida que alguns até a chamam de linguagem de programação oficial do nosso planeta.
A linguagem de programação C continua evoluindo e novos recursos vem sendo adicionado com o objetivo de moderniza-la.
O C moderno é padronizado pela ISO/IEC JTC1/SC22/WG14, essa organização padroniza a linguagem desde 1990 até os dias atuais. Vamos explorar algumas das adições feitas última década até agora.
Nesse artigo vamos documentar alguns dos novos recursos que mais achei interessante e talvez mude a maneira que você programe em C.
_BitInt
_BitInt(), antes chamado de _Extint em propóstas passadas é um tipo de largura-bit arbitrário, ou seja, permite você criar números inteiros de qualquer tamanho. É análogo ao recurso da linguagem zig que permite o mesmo comportamento.
Mas quais seriam os casos de uso do _BitInt()? Imagine que você está escrevendo um sistema de conversão de strings em Base64 para strings padrão? Um caractere Base64 tem 6 bits de largura, se usarmos um char, tipo que tem 8 bits de largura para representar cada átomo de um Base64 estariamos gastando memória atoa, então um valor de tipo _BitInt(6) seria ideal para armazenar o valor desse carectere 6 bits-wide.
Ou até pode ser usado para armazenar números extremamente grandes como no exemplo abaixo.
Exemplo _BitInt:
// exemplo trabalhando com números extremamente grandes
#include <stdio.h>
int main(void) {
_BitInt (1048576) x = ((_BitInt (1048576)) 1) << (1 << 20);
bool is_even = x % 2 == 0;
puts( (is_even) ? "2^(2^20) é par!" : "2^(2^20) é impar!" );
}Esse programa produz a saída:
2^(2^20) é par!
Atualmente esse recurso está para ser amplamente implementado depois de 2025. Atualmente até por onde eu sei apenas LLVM/Clang tem uma implementação do _BitInt.
stdarg.h
stdarg.h define comportamentos similares ao rest parameters do javascript ou kwargs do python, uma maneira de encapsular o resto dos parâmetros de uma função não nomeados.
Exemplo sobre stdarg.h da wikipedia:
// somatório de números
#include <stdio.h>
#include <stdarg.h>
// primeiro argumento é a quantidade de valores
void somatorio(int count, ...)
{
va_list ap;
int i = 0;
int soma = 0;
va_start(ap, arg1);
for (i = 0; i < count; i++)
soma += va_arg(ap, int);
va_end(ap);
return soma;
}
int main(void)
{
printf("%i", somatorio(2, 1, 3));
return 0;
}Esse programa produz a saída:
4
stdbit.h
Tratamento e criação de novos tipos de dados primitivos parecem ser um tema para o C Moderno. Foi introduzido um completo novo módulo da biblioteca padrão para justamente trazer novas operações e utilidades para números binários. Agora vou trazer uma quote traduzida da especificação atual do C23:
O Header
<stdbit.h>define macros, tipos e funções para trabalhar com a representação binária e byte de diversos tipos, tipicamente tipos inteiros. Esse header torna disponível o tiposize_te qualquer tipouintN_t,intN_t,uint_leastN_T, ouint_leastN_tdefinidos pela implementação.
Algumas de suas funcionalidades interessantes:
Funções para contagem de zeros/uns consecutivos no início e fim da stream;
Funções para verificar o primeiro e último valor de uma stream.
Checagem de um único bit
Computação do menor número de bits possível para armazenar um valor.
Imagino que funções oferecidas pelo <stdbit.h> sejam interessantes para quem trabalha com processamento de sinais, imagens ou arquivos binários.