Bonjour à tous,
Je souhaiterais créer une fonction avec un nombre variable d'argument, sans utiliser la bibliothèque stdarg. D'après les recherches que j'ai effectuées, il suffirait de récupérer l'adresse de la première variable passée en argument, puis augmenter la valeur du pointeur sur ce paramètre de la taille des paramètres passés en arguments. Donc en gros, faire ça :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
 
#include <stdio.h>
 
void f (int n, ...)
{       //En partant du principe que n indique le nombre de paramètre passés en arguments
	int *liste = &n+sizeof(int);
	for(int i = 0; i<n; i++)
	{
		liste+=1;  //On récupère l'adresse de l'argument suivant
		char carAct = *((char*) liste);
		putchar(carAct);  //On affiche l'argument
	}
	putchar('\n');
}
 
int main (void)
{
   f ((int)4, 'a', 'b', 'c', 'z');
   f ((int)7, 'x', 'v', 'a', 'm', 'e', 'a');
 
   return 0;
}
Et donc là, je devrais avoir en retour :
abcz
xvamea
Alors qu'en fait, j'obtient ça :
�a
xva

En modifiant le code de cette manière :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <stdio.h>
 
void f (int n, ...)
{       //En partant du principe que n indique le nombre de paramètre passés en arguments
	int *liste = &n+sizeof(int);
	for(int i = 0; i<n; i++)
	{
		liste+=1;  //On récupère l'adresse de l'argument suivant
		char carAct = *((char*) liste);
		printf("%i ", carAct);  //On affiche l'argument
	}
	putchar('\n');
}
 
int main (void)
{
   f ((int)4, 'a', 'b', 'c', 'z');
   f ((int)7, 'x', 'v', 'a', 'm', 'e', 'a');
 
   return 0;
}
J'obtient :
-1 0 97 0
0 4 120 0 118 0 97

Ce qui me semble malgrès tout assez étonnant...
Notez qu'au final, si je remplace par :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
 
void f (int n, ...)
{       //En partant du principe que n indique le nombre de paramètre passés en arguments
	int *liste = &n+sizeof(int)+1;
	for(int i = 0; i<n; i++)
	{
		liste+=2;  //On récupère l'adresse de l'argument suivant
		char carAct = *((char*) liste);
		printf("%i ", carAct);  //On affiche l'argument
	}
	putchar('\n');
}
 
int main (void)
{
   f ((int)4, 'a', 'b', 'c', 'z');
   f ((int)7, 'x', 'v', 'a', 'm', 'e', 'a');
 
   return 0;
}
Tout marche correctement tant que je ne dépasse pas les 5 arguments optionnels (donc la deuxième ne marche pas), et ce, quel que soit la taille des paramètres optionnels (à la légère différence qu'avec les long, il faut remplacer le sizeof int de la ligne 3 par sizeof long).
Et c'est d'ailleurs ce qui me chiffonne surtout :
Comment, peut on récupérer les valeurs d'adresses séparées de deux octets, alors que celles-ci en font 4 ou 8 (int ou long sur mon pc 64 bits)
Donc si vous avez des idées sur ce qui cloche, je suis preneur. Merci !
NB : le + 5 sert à compenser le fait que je crée des variables locales. Si il y avait 3 pointeurs locaux, j'aurais mis 13 (3*4+1).