c:accueil

Ceci est une ancienne révision du document !


Langage C

#include <unistd.h>
 
char hostname[20];
gethostname(hostname, 20);

Entre 0 et 1:

#include <stdlib.h> // rand() et RAND_MAX
#include <time.h>
 
srand(time(NULL));
 
float x = rand() / ((float) RAND_MAX); 

Entre 0 et n (exclu):

#include <stdlib.h> // rand() et RAND_MAX
#include <time.h>
 
srand(time(NULL));
 
unsigned x = rand() % n;
#warning qchose // provoque un warning à la compilation
#error qchose // provoque une erreur à la compilation
sscanf(string, "SSH-%d.%d-%[^\n]\n", &remote_major, &remote_minor, remote_version);

Le sélecteur %[^\n] ne capture pas le \n.

Source

Si on déclare et définit une variable dans un fichier d'en-tête, le linker peut rapidement générer des erreurs du type first defined here, alors qu'il pointe l'endroit de la définition.

Pour résoudre ce problème, on déclare la variable dans l'en-tête et on la définit dans le fichier source:

// .h
extern const int N_MAX;
 
//.c
const int N_MAX = 1000;

(à voir si c'est vraiment du code propre…)

Variable inutilisée

Source

static int trace_loop __attribute__((unused)) = 0;

Ne pas optimiser une fonction

float __attribute__((optimize("O0"))) scalar_avx_product(float* a, float* b)

Source

  • \r replace le curseur au début de la ligne, et écrit par dessus le contenu déjà écrit.
  • \33[2K efface toute la ligne, mais ne repositionne pas le curseur au début. À utiliser avec \33[2K\r donc.
  • \e[1;1H\e[2J efface tout l'écran

C'est la fonction atoi !

Utiliser un paramètre dans une chaîne de caractère

#define PSQR(x) printf("The square of " #x " is %d.\n",((x)*(x)))
 
PSQR(y); // The square of y is 25.
#define FORMAT "%04d"
 
printf("Value: "FORMAT"\n", value);

(source)

Utiliser un paramètre comme préfixe

#define MY_VAR(var) int var##_my;
 
MY_VAR(truc) // truc_my;
int *const ptr = &var1; // l'adresse stockée dans ptr est constante
ptr = &var2; // interdit
 
const int* ptr = &var1; // la valeur à l'adresse stockée dans ptr est constante
*ptr = 1; // interdit
 
// possibilité d'utiliser les deux en même temps:
const int* const ptr = &var1;
*ptr = 1; // interdit
ptr = &var2; // interdit
int i = 2;
int j = i++;
// j = 2 et i = 3
// retourne la valeur initiale et incrémente ensuite
 
i = 2;
int k = ++i;
// k = i = 3
// retourne la valeur incrémentée

Epsilon flottant

C'est la constante FLT_EPSILON pour les float ou DBL_EPSILON pour les double, définies dans le fichier d'en-tête float.h (source).

Pi

M_PI dans math.h

Connaître toutes les constantes définies par GCC

gcc -march=native -dM -E - </dev/null

Binder un thread sur un coeur

Sans hwloc, utiliser pthread_setaffinity_np().

En ligne de commande:

taskset -c 0 bash

Nommer un thread

#define _GNU_SOURCE // au tout début du fichier
 
// ...
 
pthread_setname_np(pthread_self(), "Thread foo");

Le nom du thread est limité à 15 caractères. Cette fonction n'est pas portable.

Ajouter un certain nombre de zéros en préfixe (et ne pas les afficher si le nombre est suffisamment grand): %02d (pour 5 affiche 05 et pour 15 affiche 15). On peut se servir de cette technique pour forcer un espace si le nombre est positif et remplacer cet espace par le signe négatif sinon: % 2d. Dans le cas où on a toujours le même signe, le caractère espace n'est pas nécessaire.

#if defined(__x86_64__)
printf("x86_64 !\n");
#else
printf("autre\n");
#endif

Voir https://sourceforge.net/p/predef/wiki/Architectures/ pour une liste de possibilités.

Il y a aussi cette page qui permet de tester plein de choses.

Ce mémo est aussi intéressant.

Déclarer la variable de préprocesseur NDEBUG avant l'inclusion de assert.h (source)

Source

#include <stdio.h>
#include <io.h>
 
if (isatty(fileno(stdin)))
    printf("stdin is a terminal\n");
else
    printf("stdin is a file or a pipe\n");

Compiler avec l'option –fstack-protector-all. L'option -fsanitize=address aide aussi.

Source

#include <execinfo.h> /* backtrace, backtrace_symbols_fd */
#include <unistd.h> /* STDOUT_FILENO */
 
void print_stacktrace(void) {
    size_t size;
    enum Constexpr { MAX_SIZE = 1024 };
    void *array[MAX_SIZE];
    size = backtrace(array, MAX_SIZE);
    backtrace_symbols_fd(array, size, STDOUT_FILENO);
}

On peut ensuite connaître la ligne du fichier source correspondant à l'adresse donnée dans la pile d'appels avec :

addr2line -e main.out 0x4007db
#!/bin/bash
 
readonly BACKTRACE_FILE=$1
 
for l in $(grep -E "^/.+\(.+\)\[.+\]" $BACKTRACE_FILE)
do
	lib=$(echo $l | sed -E "s/(\/.+)\(.+/\1/g")
	addr=$(echo $l | sed -E "s/.+\((.+)\).+/\1/g")
	ans=$(addr2line -e $lib $addr)
	if [[ $ans == "??"* ]]
	then
		echo $l
	else
		echo $ans
	fi
done
gcc -E source.c

Ajouter l'option -fdiagnostics-color=always à la commande gcc (source).

Mécanisme qui permet de choisir quelle fonction associer à un symbole lors de la résolution des symboles lors du lancement d'un binaire.

Dans un fichier asan.supp :

leak:libdbus-1.so
LSAN_OPTIONS=suppressions=asan.supp,print_suppressions=0 ./programme
  • c/accueil.1742139526.txt.gz
  • Dernière modification : 2025/03/16 16:38
  • de phsw