Petites fonctions en C bien utiles

Bonjour,

Un petit forum sur : pourquoi tu post ?

  • Ben pour te faire bouler …

Bon alors on recommence pour M. susceptible :

Bon voila une de mes fonctions supportée par pas mal de compilateur (c’est effectivement du hors normes) :

void trace( Char *Fmt, ... )
{
     int  *AddrArgVar = (int *)(&Fmt)+1;  // AddrArgVar pointe sur le premier argument variable
     char buf[4096];


     /* Ici on utilise les foncionnalites des fonctions de style printf  
      * pour decoder les arguments variables
      * (plutot que de ré-écrire un printf avec des va_list)
      * 
      * Remarque : Seul les 20 premiers arguments seront utilisés
      */
     _snprintf( buf, sizeof(buf)-1, Fmt, *(AddrArgVar),
                                         *(AddrArgVar+1),
                                         *(AddrArgVar+2),
                                         *(AddrArgVar+3),
                                         *(AddrArgVar+4),
                                         *(AddrArgVar+5),
                                         *(AddrArgVar+6),
                                         *(AddrArgVar+7),
                                         *(AddrArgVar+8),
                                         *(AddrArgVar+9),
                                         *(AddrArgVar+10),
                                         *(AddrArgVar+11),
                                         *(AddrArgVar+12),
                                         *(AddrArgVar+13),
                                         *(AddrArgVar+14),
                                         *(AddrArgVar+15),
                                         *(AddrArgVar+16),
                                         *(AddrArgVar+17),
                                         *(AddrArgVar+18),
                                         *(AddrArgVar+19) );

     /* Initialise la fin de chaine a 0 
      *(pour eviter les plantages memoires mais certainement superflux)
      */
     *(buf+sizeof(buf)-1) = 0x00;

     /* Affichage du resultat a l'ecran avec un petit texte 
      * devant qui pourrait etre l'heure par exemple
      */
     printf( "%-15.15s %s\r\n", "exemple de trace", buf );

     /* Ou encore dans une fenetre a la windows ou ...
      */
     MessageBox( NULL, buf, "trace", MB_OK );


}

// Ca s'utilise comme ca :
// trace( "Valeur de X:%d et de S:%s", X, S );

qui dit mieux ?

Pour info: les balises [ CODE ] ne permettent pas d’inserer des espases (respecter les identations).
J’ai été obligé de mettre plusieur fois & nbsp; a la place ce qui n’est pas pratique.
Pareil pour le signe + ou je suis obligé de mettre & #043;
Edité le 30/10/2007 à 01:20

Heu :

  1. y a pas de commentaires, donc nulle. (une fonction ou méthode non commentée ne mérite pas d’être utilisée sauf à très bas niveau, et encore…)

  2. si c’est pour faire du printf, autant faire ça :

#define trace(args) {printf("%s:%d: “, FUNCTION, LINE); printf args; printf(”\n");}

Et l’utilisation est d’autant plus simple : trace(("%s", “test”));

Voilà. C’est méchant, mais quitte à se prendre pour le meilleur codeur du monde, autant apprendre à descendre bien plus bas :slight_smile:
Edité le 29/10/2007 à 22:25

Je dirais que selon le Chat de Schrödinger, avec un vent tournant Nord, Nord-Est et une probabilité de 50%, il y a une chance sur deux que cette fonction ne soit pas ton fruit, et une chance sur deux que tu connaisses le langage en question. Rappelons que je n’ai pas toujours raison, mais que j’ai jamais tort.

Mieux :neutre:

Le pire étant que normalement il faut utiliser les va_list pour manipuler les arguments “infinis”, ie:

cf. homepage.mac.com…

void foo(type arg, ...) {
  va_list va;
  va_start(va, arg);
  while (1) {
    if (done) break; 
    typeN e = va_arg(va, typeN);
  }
  va_end(va);
}

Et au contraire, ce qu’il fait n’est pas portable, et surtout j’imagine à peine le bordel si jamais il passe des objets dépassant la taille d’un int…

Sur ce, bonne nuit!

Bien repondu jmgchouchou :wink:

Bon sinon Sans-Nom merci de ta reponse. tu viens de me degouter de poster sur ce forum. :frowning:

Disons que tu n’as pas fait la meilleure entrée avec tes grosses chevilles et ton code buggé :wink:

C’est pas grave, c’est l’occasion de voir qu’au moins, en Java, les varargs c’est facile pour tout le monde, et ça bousille pas la mémoire. :o

:paf:

Salut a tous,

Bon déjà ce post s?intitule : Petites fonctions en C bien utiles.

Donc vous pouvez poster des petites fonctions que vous trouvez sympathique.

Puis ça serait bien par respect du posteur, d?être objectif dans vos remarques.

Du style :

  • oui mais cette fonction n?est pas portable, il vaut mieux utiliser les va_list ? (c?est vrai, si la portabilité est votre soucis)
  • Un petit lien sur les arguments variables : sympathique pour approfondir le sujet.

Le reste du style :

  • ouais c?est buggé espèce de blaireau va décrotter tes sabots?

n?est pas très utile.

Sinon pour ton exemple sur les va_liste : c?est pas toi qui m?a fait une remarque sur les commentaires ? (que j?ai rajouté d?ailleurs) Tu pourrais au moins préciser ce qu?est : type, typeN, et puis surtout done, car je suis pas sur que ce soit très claire pour tout le monde ? (sauf si tu me dis que ya jamais personne qui vient sur ce forum et que ya que toi dans quel cas je perds mon temps)

Bon et puis vous pouvez imaginer ce que vous voulez, même que cette fonction est buggé. Mais imaginer ne veut pas dire qu?elle est !
Alors étayer un peu avant de dire que ya des bugs. (Un exemple pour reproduire le bug par exemple).

Et si, après ce mauvais départ ce post intéresse quelques personnes plus objectives, bien je vous en donnerais d?autres.

Bonne journée.

Hé, kirol, c’est pas que j’ai envie de te dégouter de quoi que ce soit hein. C’est juste qu’avant de se la péter sur un code, de frimer, on regarde un tant soit peu ce qu’on fait, ce qu’on a fait (=expérience en C), et surtout est-ce que ça n’a pas déjà été fait.

Car certes, c’est des vilaines va_list qui font passer les varargs Java** pour de la pitance pour prisonniers gobelins*, mais ton code, miam, autant passer un pointeur sur un tableau d’int, hein… car c’est tout ce que ça fait.

Alors que :

  1. va_arg se préoccupe de la taille en mémoire des arguments
  2. va_arg est éprouvée.

Ceci dit, j’vois pas pourquoi je m’excuse d’être méchant, cynique, et irascible?

  • encore que ces derniers - s’ils n’étaient pas avares - peuvent bien nourrir les dits prisonniers, afin qu’ils soient bien gras.
    ** varargs Java disponibles qu’en Java*** 1.5, et que c’est vrai que c’est plus sécurisé, mais en fait un varargs Java, c’est qu’un pauvre tableau de références sur des objets.
    *** dont les serveurs d’applications, et Eclipse, sont la preuve de la lourdeur du bousin qui contrairement au langage C - certes vieux, certes pas “objets”, certes pas pour personne atteinte d’alzeimer et oubliant à tout va de libérer la mémoire (et les ressources en fait, mais c’est pareil en Java) - ne fonctionne pas dans 100% avec une machine virtuelle lourde (ah ça, le langage est rapide, d’ailleurs moi quand je suis sous Eclipse, j’ai des fois des beaux freeze**** de l’application, ça va trop vite, alors j’ai même pas vu le changement!)
    **** même que si l’application pouvait exploser, hé bien c’est ce qu’elle ferait, car ça y ressemble franchement.

  1. La portabilité doit être un souci. Ca veut surtout dire 1) ça compile partout 2) ça s’exécute partout.
  2. Et ça? (donné dans mon second post) homepage.mac.com… Sinon, tu as google hein…
  3. done = fini. ie: si jamais tu as fini de lire les arguments, tu t’arrête. Au cas où tu ne l’aurais pas remarqué, while (1) = boucle infinie (à remplacer par for ( ; ; ) c’est mieux).
  4. typeN = type de l’argument en n-ième position. Ce qui en regardant le code me semble censé : on fout toujours un type à côté d’une déclaration de variable.
  5. dans un monde où sizeof(long) = 8, sizeof(int) = 4, trace(“foo %d bar %d”, 36, (long) 79); n’affiche pas ce que tu veux selon l’agencement des octets en mémoire (byte order, etc).
  6. snprintf : si y a un "" devant, c’est que c’est une fonction que tu n’es pas censé utiliser… (sûrement, sinon snprintf n’existerait pas pour rien)
  7. tu te limites à un buffer de 4096. Réfléchis bien: tu affiche la chaîne après. Pourquoi ne pas laisser printf, et vprintf faire entièrement le sale boulot? ie:
void trace(const char* fmt, ...) {
  va_list va;
  va_start(va, fmt);
  printf("...."); vprintf(fmt, va);
  va_end(va);
}

Oh, et j’ai pas fait de C depuis longtemps, donc pour les signatures des fonctions, y a le man qui traîne sur google je pense.

D’autres choses?
Edité le 30/10/2007 à 11:45

Non mais o. stop.

Et arrêtes de dires que ma fonction gère que des int. yen a qui vont y croire avec les 2 pages de baratins que tu colles.

Du plus arrêtes de focaliser sur le printf. Car on sent branle du printf.

La fonction sutilise de la manière suivante :

trace( "Valeur de X:%d et de S:%s D :%f", X, S, D );

X étant un int ou un short ou un long
S un type char *
D un type float, double

Cest quoi qui te fais dire ça ? cette ligne :

int *AddrArgVar = (int *)(&Fmt) +1;

ben tu peux la remplacer par ca si ca te fais plaisir
(pour un compilateur 32bits)

char *AddrArgVar = (char *)(&Fmt) +4;

puis le reste aussi

  _snprintf( buf, sizeof(buf)-1, Fmt, *(AddrArgVar),
                                         *(AddrArgVar +4),
                                         *(AddrArgVar +8),
                                         *(AddrArgVar +16),

Et la tu vas dire : mais ta fonction ne gere quun tableau de char ? Ou peut etre char * ?

une variable 8bits, 16bits 32bits , 64bits ou encore une structure de x octets a une adresse qui est soit 16bits soit 32bits ou aussi 64bits suivant le système utilisé.

Perso utilisant un compilateur 16bits et un compilateur 32bits je preferes cette notation :

int *AddrArgVar = (int *)(&Fmt) +1;

qui fonctionne dans les 2 cas (int = 16 bits sur compilature 16bits, int = 32 bits sur compilateur 32bits ) soit la taille dune adresse memoire sur les 2 types de compilateur.

Mais celle la serait a mon avis compatible avec les compilateur 64bits :

void *AddrArgVar = (void *)(&Fmt) +1;

Alors toi qui es si soucieux de la portabilite note deja ca.

4096 ben tu peux mettre 100 si tu veux (pour une trace ca devrait le faire).

Pi je ne fais pas quun printf car dans cette exemple le resultat obtenu serait sur lappel de :

trace( "Valeur de X:%d et de S:%s D :%f", X, S, D );

exemple de trace Valeur de X :10 et de s :boujour D :0.552235

Mais bien sur peut etre modifié par exemple pour avoir un truc du style
30/10/2007 15:08 192.168.1.2 56845 20 >> Valeur de X :10 et de s :boujour D :0.552235

56845 : le ThreadID par exemple
20 : etant lage de ta soeur :wink:

puis aussi envoyer à la fin dun fichier de traces plutot qua lecran
puis gerer un niveau de trace jen sais rien quoi : laisse faire ton imagination au mieu de focaliser sur 4 pauvres lignes de codes pour lesquels systematiquement tu vas critiquer.

Pi vais pas te poster une fonction de trace sur 4 pages cette exemple est significatif et devrait (sauf le MessageBox) compiler sur windows et unix/linux. (Effectivement avec un compilateur GCOS cest pas sur mais a mon avis le mien a peut etre plus de chance de compiler que le tiens avec des va_list :wink:

Et puis va_args va_start ect ne sont pas des fonctions mais de #define (juste comme ca pour info) As tu été jeter un coup dœil sur ce que ca fesais ?

pi tu peux utiliser snprintf si ca te chante ou ce que tu veux aussi.
Mais sache encore une fois que si jai utilisé _snprintf a un moment ou a un autre cest encore pour certainement une raison de portabilité.

Quant à la question de portabilité :

La portabilité doit être un souci : parles pour toi. Ta java pour ca. (Perso je connais pas. Mais vu a la vitesse que tournent les progs écrit en java ça mattire pas trop pour linstant : serait-ce le triste revers dune portabilité infaible ?)

As tu essayé de copier/coller mon code dans ton compilateur preferé avant de dire que ca ne compilerai pas partout ?

Bon et puis arretes de dire qui c’est de la frime ou je sais quoi ?
Cette fonction est faite pour ceux qui jugeront qu’elle peut leur servir. Serieusement, qu’est ce que j’en ai a branler de ces 4 pauvres lignes de codes qu’ont ete ecrite depuis deja plus de 15ans. As te dire ya des gens qu’on des softs qui tournent depuis plus de 15ans avec cette fonction. Pi je peux t’assurer que t’es aller chez eux et que des données te concernant son passé dans cette fonction. Alors ta bouche avant de vouloir la ramener et pourrir mon post.

Pour finir, la science peut etre effectivement tiré dun bouquin. Lexperience certainement pas jeune isolent. Non mais lautre, qui metait encore des couches quand je codai deja ? :wink:

Magnifique.

J’ai jamais dis que c’était uniquement pour des int. Je t’ai juste montrer un cas où ça pouvait rater. Jusqu’au jour d’aujourd’hui, les fonctions de la famille printf ne travaillent pas qu’avec des pointeurs, et donc travaillent aussi avec des données brutes.

ie:

typedef union {int x; struct {int x, y, z;} y} a;

Si je reprend ton code, donc:


a = {{9, 10, 11}};
a.x = 9; /* pour être sur */
trace("super %d ça marche %d", u, 7);

je devrais avoir ça :

... super 9 ça marche 7

Mais hélas, non :

... super 9 ça marche 10
snprintf( buf, sizeof(buf)-1, Fmt, *(AddrArgVar), *(AddrArgVar+1), ...);

J’ai beau n’avoir commencé le C que depuis 2000, mais pour moi :

AddrArgVar : int* -> *AddrArgVar : int

Donc on a (au niveau des types, maintenant ça fait pas 23 ans que je fais du C (rapport à mes couches culottes, tout ça) donc :

snprintf( char*, size_t, char*, int, int, ...);

Il est vrai qu’ensuite, ça marche d’enfer… mais tu vois, ces va_list, elles servent à ça : faire les choses proprement, et ne pas caster un XXX en int.

Parce que vois-tu, tu as l’air de critiquer Java sans le connaître, mais un tel langage (même si la JVM est lourde, on peut tolérer deux
trois trucs de la part d’un serveur d’application ou d’un IDE) aurait déjà piqué sa crise avec un ClassCastException (ie: tu passe un objet de type T vers le type U, sans qu’il n’y ait de relations).

Il n’y a même pas à remplacer la ligne :

int *AddrArgVar = (int *)(&Fmt) +1;

Par je ne sais quel artifice - et je rappelerai que pour faire du C portable, la ligne suivante doit être modifiée comme telle :

char *AddrArgVar = (char *)(&Fmt) + 4;
char *AddrArgVar = (char *)(&Fmt) + sizeof(int);

puis le reste aussi

  _snprintf( buf, sizeof(buf)-1, Fmt, *(AddrArgVar),
                                         *(AddrArgVar +4),
                                         *(AddrArgVar +8),
                                         *(AddrArgVar +16),

Tandis qu’il ne me semble pas que l’arithmétique sur pointeurs sur rien (void*) soit tolérée (maintenant, je le répète, j’ai 1) pas fait de C depuis longtemps 2) pas de compilateur sous la main).

ie:

void* AddrArgVar = (void *)(&Fmt) + 1;

Ne compile pas, ou ne devrait pas.

Pour cela, tu as déjà des outils, notamment syslogs sous Unix (voir man, et je suis sûr que les petits gars de gnuwin32 ou mingw ont fait un truc portable, ou que MS a une API bien a elle).

Quoique ça fasse, ça le fait “proprement”. va_arg() doit je le suppose juste renvoyer un truc du genre ((type*) ptr).

PS: _snprintf c’est une fonction Win32 à la base, histoire de palier aux défauts de C89/ANSI où sprintf existe, mais bonjour les buffer overflow. Par contre, je sais pas pour C99. En outre :

  1. _snprintf n’est pas portable (car MS Win32, même si ça fait la même chose que snprintf). Donc ça ne compile pas sous un gcc version Linux…

  2. snprintf n’est pas C ANSI, mais évite un buffer overflow, et c’est énervant que ce soit pas C ANSI.

Pourquoi?

Tu viens poster une fonction en disant que ça serait utile. On ne fait que te répondre. Ce que la réponse du berger à la bergère, hein…

Ca fait un peu hautain - ensuite - de dire qu’elle fonctionne (?) sur tous les compilateurs quand via de la logique pure (du moins, je
l’espère).

Y a 15 ans, ça nous fait 1992. Soit trois ans de plus que le C Ansi…

Au passage,

  1. c’est pas parce qu’une fonction compile qu’il n’y a pas de problèmes

  2. c’est pas parce que jamais personne ne s’est plaint qu’il n’y a pas de problèmes, ça peut être que la fonction n’est pas utilisée, ou que les cas d’erreurs ne se sont jamais présentés (c’est vrai qu’il fallait osé utiliser un union pour que ça plante, mais taquin et
    demi!).

Mon expérience? Bah certainement que 5 ans, je le crains.

Tss.

PS: au passage, Java est “portable” (compile one, run
everywhere
) par nature, puisque ça utilise une machine virtuelle,
ie: un pc dans ton pc. Maintenant, c’est vrai que l’adage c’est
plutôt Compile once, run nowhere, mais ça…
Edité le 30/10/2007 à 17:41

hum… apparemment c’est un genre de TU de petit code, alors sans transition et pour changer de sujet, je vous soumet le mien :smiley:

RAWREAD.exe
ça sert à backuper une image de disquette dans un fichier qui peut être réécrit sur dk par l’utilitaire rawwrite.exe fourni avec linux.
Sur la distrib de l’époque il n’y avait pas l’utilitaire inverse, javais codé ça rapidement :neutre:


#include <bios.h>
#include <stdio.h>

#include <fcntl.h>
#include<io.h>
//windows specific!
#define NB_TRACK 80 // àrevoir
#define NB_SECTOR 10
#define NB_HEAD 2
#define SECTOR_SIZE 512

   #define CMD    2    /* read sector command */
   #define DRIVE  0    /* drive number for A: */
   #define NSECT  1    /* read sector count */


//int      _RTLENTRY biosdisk(int __cmd, int __drive, int __head, int __track,
//                            int __sector, int __nsects, void _FAR *__buffer);

short segment(short * pointeur)
{
	return pointeur[0];
}

short offset(short * pointeur)
{
	return pointeur[0];
}

/*
Command-line Dos program.
read the floppy disk in a: and write the raw data into the "disk.img" file.
usage: launch "rawread.exe" with no arguments.
*/
int main(int argc,char* argv[])
{
	int track;
	int sector;
	int head;
	int handle;
	char buffer[SECTOR_SIZE];
   int result;

	handle = open("disk.img",O_CREAT);
	for(track=0;track<NB_TRACK;track++)
	for(sector=0;sector<NB_SECTOR;sector++)
	for(head=0;head<NB_HEAD;head++)
	{
   	   printf("Attempting to read from drive A:\n");
	   result = biosdisk(CMD, DRIVE, head, track, sector, NSECT, buffer);

	   write(handle,buffer,SECTOR_SIZE);
   }

	close(handle);
	return 0;
}

voilà, c’est pas ANSI, ça tournait sous Windows.
:slight_smile:

Edit: à compiler sous Turbo C de Borland.

sinon, il faut implémenter la fonction biosDisk qui se base tout simplement sur la fonction int 13h du BIOS: ça fait que ça fonctionne que sous DOS, je n’ai jamais trop cherché l’équivalent windows.
en.wikipedia.org…
Edité le 31/10/2007 à 09:54

(bien que j’avais esperé une autre tournure pour ce post)

Il est vrai que cette partie de code faut l’oublier

void* AddrArgVar = (void *)(&Fmt) + 1;

impro (oups) Mais je suis bien contant que tu es relevé cette erreur. (au moin yen a un qui s’interresse a ce post et pour qui ce que je dit (pour une fois) n’est pas du chinois)

bon pour le buffer overflow du _snprintf c’est peut etre pour ca que j’avais rajouté la ligne
*(buf+sizeof(buf)-1) = 0x00;
et passé sizeof(buf)-1 a la fonction (a la place de sizeof(buf))

bon et puis tu peux utiliser un sprintf si t’as pas snprintf (avec un buffer a 4096) faudrait une sacrée trace pour planter ton programme. (mais bon je vois que monsieur est senssible au enventuelle probabilite de bug) j’aimerai bien voir un petit morceau de ton code juste pour voir si il est a la hauteur de ce que tu voudrais me laisser croire : du code sans faille, portable au possible …

(j’espere que c’est pas toi qu’a devellopper le tratement de la balise [ CODE ] ? (non la j’abuse lol)

Concernant ton test sur l’union il est vrai que seul a ma connaissance (qui reste limité parcequ’apres tu vas dire que c’est de la frime), les struct sont passées par valeur au fonctions (et non par adresse pour les autres) Et d’ailleur c’est bien partique pour pouvoir interfacer du C avec d’autre langage comme un compilateur PASCAL que j’utilise.

si (j’ai bien compris) ton code est le suivant :

          typedef union {int x; struct {int x, y, z;} y; } a;

          a u;

          u.y.x = 9;
          u.y.x = 10;
          u.y.x = 11;

          u.x = 9; /* pour être sur */ 
          trace( 0, NULL, "super %d ca marche %d ", u, 7 );          

n’esperes pas plus d’obtenir ce que tu veux en remplacant trace par un printf (que ce soit un gars du gnu ou pas qu’a ecrit le printf):

printf( "super %d ca marche %d", u, 7 );

Pour cela il faudrait que tu ecrives ton propre type pour printf du style : %z (si ca sert pas deja (la c’est encore de l’impro))

printf( "super %z ca marche %d", u, 7 );

pour gerer ton propre saut en memoire va_list ou pas

un code politiquement plus correcte serait du style (bien que la politique c’est pas mon truc :wink: :

trace(  "super %d ca marche %d", u.x, 7 ); 

ou encore

trace(  "super %d ca marche %d", *(int *)&u, 7 ); 

mais la ca devient chaud (pour toi).

Et puis je voulais juste me citer :

ca c’etait pour :

Bon et puis les va_list je suis pas contre, mais si tu veux faire ce que fait ma petite fonction de 4 lignes avec des va_list ben te faudra plus de 4 lignes : re-ecrire le printf quoi (en gerant les trucs du style %-15.15s bien sur) !

bonne soirée.

Merci deltree tu me sauves. Je t’en dois une maintenant :wink:

Ca compile plus maintenant (sous win2000 par exemple avec un bios.h adequat ) ?

Tu connais pas un equivalent (appels au bios ou … ) pour faire la meme chose sur un CD/DVD (un acces raw ?)

bon courage avec sans-nom (c’est moi qui vais rigoler maintenant lol)

Note:
Bon je sais je vais encore etre chiant avec les balise [ CODE ]
mais le copier/coller de code genre celui de deltree sur ce site dans notepad chez moi : ben ya pas les retours a la ligne.
Je precise que j’utilise FireFox (au cas ou)

En plus de 4 lignes? Tss…

Juste parce que j’ai déjà écrit ce genre de truc (ça marche en C99):

void trace(  const char * filename, const unsigned int line,  const char* function, const char* format, ...) {
  char buffer[4096] = new char[4096];
  va_list va;
  va_start(va, format);
  vsnprintf(buffer, 4096, format, va);
  va_end(va);
  // sortie
  fputs(buffer);
}

[au passage, dois je considérer comme stupide le fait de reprendre du déjà fait pour faire plus de quatre lignes?]

Pour _snprintf … je dis juste qu’elle gère déjà le cas du buffer overflow en n’écrivant pas plus de n bytes… à la différence de la fonction C ANSI sprintf. Et _snprintf, c’est Microsoft… donc difficilement portable (portable = qui tourne/compile ailleurs que sous Windows, quand même:))

C’est justement parce que tu passes ce que tu veux, et que tu fournis un format particulier (%d dans le cas présent, ie: tu analyses le second argument comme un entier!). Oui, je triche car le compilateur n’y voit que du feu.

Et ce n’est pas le seul cas qui peut foirer hein. Je l’ai dis, si jamais sizeof(int) = 4 & sizeof(long) = 8 (c’est tout à fait possible), alors ton truc plante aussi…

trace( "super %d ca marche %d", *(int *)&u, 7 );  

Très intelligent de caster l’adresse d’une union en pointer sur int, puis retourner la valeur… mais parfaitement inutile. Preuve que tu manipules :slight_smile: (relis ce que je viens d’écrire dans ce message, histoire de ne pas y voir que du feu).

En premier lieu, on ne sait jamais. Justement, un buffer overflow ça peut être justement faire ce qu’il faut pour tromper le programme et en injecter un autre.

Je t’ai prouvé (encore une fois) qu’il y a bug, en prenant des cas pratiques qui peuvent se produire. Y a pas besoin de faire des artifices avec des union pour les avoir, c’est sujet à bug. maintenant je m’en fous, j’utilise les va_list qui ne sont certainement pas belles en elles-même (c’est une macro, et quelle macro, mais je m’en tape)

En second lieu, non. Jamais je ne qualifierai mes codes de sans faille. D’une, parce que je suis humain, que je fais des erreurs, et de deux, parce qu’un code parfait*, ça n’existe pas. De deux, parce qu’un programme, c’est un ensemble de code, sur des environnements différents qui peuvent interagir de manière inattendues. Par contre, oui, peut-être qu’ainsi mes codes me font le moins de surprises possibles une fois mis ensembles.

Quant à la portabilité, bah … faut dire que bosser sous Windows pour cause de flemingite aigue d’installer linux, et devoir rendre des projets qui tournent sous Linux, ça aide déjà plus que de passer d’un compilateur Borland à Intel, tout deux pour Windows… y a certainement moins de risques (quoique).

J’ai même été jusqu’à faire fonctionner quasiment sans anicroche un code réseau codé sous Windows, à la porco sous Linux… bon, le fait est qu’avec deux heures pour tester, sous Windows uniquement, ça ne risquait pas de fonctionner parfaitement :slight_smile: (disons qu’en ayant un client et un serveur autre que la même machine, ça ratait :))

deltree> mince :slight_smile: j’avais pas réalisé que tu avais du C avant de faire de l’ignoble Java! :slight_smile:

  • un code parfait, c’est avant tout un code mauvais : comment on vend des mises à jour de code à cause de bug au client sinon?

[quote="kirol"] Merci deltree tu me sauves. Je t'en dois une maintenant ;)

Ca compile plus maintenant (sous win2000 par exemple avec un bios.h adequat ) ?

Tu connais pas un equivalent (appels au bios ou … ) pour faire la meme chose sur un CD/DVD (un acces raw ?)

bon courage avec sans-nom (c’est moi qui vais rigoler maintenant lol)

Note:
Bon je sais je vais encore etre chiant avec les balise [ CODE ]
mais le copier/coller de code genre celui de deltree sur ce site dans notepad chez moi : ben ya pas les retours a la ligne.
Je precise que j’utilise FireFox (au cas ou)
[/quote]
Malheureusement, c’est un problème connu, et dénoncé vilement à la team Clubic. J’avais déjà fait part du bug, qui est lié à l’utilisation d’une propriété CSS plutôt que la balise

 fait pour ce genre de truc.

(bon, on pourra arguer aussi que c’est de la faute à Fx de pas respecter la mise en page dans son copier coller, …)

Et si tu veux que j’sois méchant avec deltree (y a pas de raisons, même pour les habitués), bah son code devrait faire attention aux cas d’erreur (surtout si la création du fichier foire).

Pour le reste, j’connais pas l’API bios.h (à cela, je répondrai que a) j’ai jamais utilisé de disquettes dans mes programmes b) je connais pas suffisamment les fonctions systèmes pour en parler)

oops, c’est TurboC (de Borland) qu’il fallait utiliser pour compiler mon truc.
je vais éditer poour préciser.