30

Pareil. Mais c'est pas très utilisable pour une appli finalisée, surtout si les utilisateurs sont pas des codeurs.
avatar
Zeroblog

« Tout homme porte sur l'épaule gauche un singe et, sur l'épaule droite, un perroquet. » — Jean Cocteau
« Moi je cherche plus de logique non plus. C'est surement pour cela que j'apprécie les Ataris, ils sont aussi logiques que moi ! » — GT Turbo

31

Ah ?
ASSERT(3)                           Linux Programmer's Manual                           ASSERT(3)

NAME
       assert - abort the program if assertion is false

SYNOPSIS
       #include <assert.h>

       void assert(scalar expression);

DESCRIPTION
       If  the  macro  NDEBUG  was  defined at the moment <assert.h> was last included, the macro
       assert() generates no code, and hence does nothing at all.

Donc il serait standard (???) de passer -DNDEBUG en release, et pas en debug. Ca veut dire que #ifdef NDEBUG suffit à savoir si on exécute en debug ou en release.

Sinon, je sens que je vais me faire mes macros, qui vont ressembler à assert, parce que c'est bien commode en effet. smile

32

Non non -g ne joue pas sur NDEBUG, c'est a toi de l'activer ou non avec ta compilation
avatar
Proud to be CAKE©®™


GCC4TI importe qui a problème en Autriche, pour l'UE plus et une encore de correspours nucléaire, ce n'est pas ytre d'instérier. L'état très même contraire, toujours reconstruire un pouvoir une choyer d'aucrée de compris le plus mite de genre, ce n'est pas moins)
Stalin est l'élection de la langie.

33

Folco > en cas de condition fausse, en mode debug assert() affiche la condition et termine le programme, et en mode non debug ça ne fait rien du tout. Ça ne permet pas de tolérer les erreurs temporaires, ni d'afficher un message user-friendly.
avatar
Zeroblog

« Tout homme porte sur l'épaule gauche un singe et, sur l'épaule droite, un perroquet. » — Jean Cocteau
« Moi je cherche plus de logique non plus. C'est surement pour cela que j'apprécie les Ataris, ils sont aussi logiques que moi ! » — GT Turbo

34

Zerosquare (./30) :
Pareil. Mais c'est pas très utilisable pour une appli finalisée, surtout si les utilisateurs sont pas des codeurs.

Tout à fait d'accord.

Folco: Ca permet de mettre des conditions que tu supposes vrai dans le code.
Ca facilite énormément le déboggage et la maintenance (surtout avec une suite de test assez complète).
Exemple: MAY_ASSERT(n >= 2); for(int i = 0; i < n ; i++) { ... }
(accessoirement en mode release, mes assert se transforment en assume, ce qui permet à un bon compilateur de produire du code encore plus efficace: dans l'exemple ci dessus, gcc ou visual c++ ou clang ne généreront pas l'instruction initiale pour vérifier que n vaut 0 dans la boucle for. En mode debug, si c'est pas vrai, ca m'arrête le programme brutalement).

35

GT en mode 68000 :

Mon cher Folco, voila comment je fais en 68000 (J'ai exactement le meme problème que toi, langage de haut niveau hum hum...)

jsr Ma_procedure
bmi Elle_vient_de_planter (Probleme dans la proc)
...
....
...

Ma_procedure
movem.l d0-d7/a0-a6,-(a7) ; On sauve les regs
... ton code
..; d0 contient un positif si tout va bien, un négatif si ca foire
tst.l d0
movem.l (a7)+,d0+d7/a0-a6
rts

(Le movem et le rts modifie pas les codes conditions wink )

Ceci est un 'presque troll' mais les 68000 eurs comprendront.

Par contre le prochain qui me dit que le goto c'est de la m.... je lui en ai met une tongue. Car sans goto on aurait pas de if (ben oui on ferait comment pour sauter a travers la portion de code ? hein ?)


GT Membre du front de libération du Goto !!
avatar
Accrochez vous ca va être Cerebral !!

36

Oui, je sais comment fonctionne assert, mais je me suis mal exprimé en ./31, ou du moins, j'avais mal compris le ./30 de Zerosquare ^^
Effectivement, assert permet de vérifier que tout va bien quand on débogue, mais ça ne met pas en place un mécanisme correct de gestion d'erreur en mode release, j'en ai bien conscience.

Godzil -> Je n'ai pas dit ça, je fais bien la différence entre des symboles de debug et un symbole de préprocessing.

37

GT -> grin
Ah oui, je t'ai pas dit dans le mail, mais les movem sur tous les regs alors que yen a que la moitié qui sont utilisés, c'est pas la peine tongue
Et je sais que movem et rts ne modifient pas les flags ^^
Ya tout plein de manière de gérer les erreurs en asm, mais je me prends même pas la tête parce qu'il y a une façon optimale à chaque fois, et pas une façon générique.

Tiens, par exemple, ici je teste un résultat qui peut être -1, 0, 1, ou 2 :
	tst.w	d0
	beq.s	\Valid
	bmi	ErrorFileCorrupted
	subq.w	#1,d0
	beq	ErrorFileNotFound
	bra	ErrorWrongFileType

Donc ça dépend complètement des fois. wink

38

un peu H.S., mais pour la culture : en Scala, tout est fait pour ne pas utiliser d'exceptions, il est conseiller de gérer les erreurs via les types : les fonctions renvoient un résultat de type Résultat ou de type Erreur (ça revient plus ou moins à renvoyer une valeur spéciale, finalement, donc cas 1). Sauf que quand tu utilises le résultat, le compilateur est capable de se rendre compte si tu prends tous les cas en compte (donc les erreurs) ou pas. Du coup, ça permet d'avoir beaucoup plus de garanties grâce au système de types.
avatar
<<< Kernel Extremis©®™ >>> et Inventeur de la différence administratif/judiciaire ! (©Yoshi Noir)

<Vertyos> un poil plus mais elle suce bien quand même la mienne ^^
<Sabrina`> tinkiete flan c juste qu'ils sont jaloux que je te trouve aussi appétissant

39

Intéressant comme concept, pouvoir modifier analyser les types à la volée ^^ Ca coûte peut-etre cher en ressources par contre.
GT Turbo (./35) :
les 68000 eurs comprendront.
Je crois que tout le monde l'est ici grin

40

Pas forcément : le gros du travail (l'inférence de type et les vérifications qui vont avec) est fait à la compilation. Un des buts de ce genre de langages est de vérifier le maximum de propriétés lors de la compilation, pour avoir autant de garanties théoriques sur l'exactitude de ton code.
avatar
<<< Kernel Extremis©®™ >>> et Inventeur de la différence administratif/judiciaire ! (©Yoshi Noir)

<Vertyos> un poil plus mais elle suce bien quand même la mienne ^^
<Sabrina`> tinkiete flan c juste qu'ils sont jaloux que je te trouve aussi appétissant

41

Ok, merci. smile

PpHd -> ta macro ASSUME, elle ressemble à ça ? https://freedesktop.org/patch/34398/

(et c'est quoi ce have_builtin_unreachable au passage ? yen a qui s'éclatent avec le préproc, c'est fou ça grin)

42

les buitins c'est des bouts de code rajoutes en dur par le compilo parce que le C ne sait pas le faire. genre alloca, qui fait un malloc dans la pile et n'a pas besoin de free (c'est libere quand le stack frame saute) jardine dans la pile, donc pour que ce soit portable, on fait un __builtin_alloca() et quand il le voit, le compilo lui meme remplace cet appel par le code kivabien.

43

44

Folco (./41) :

(et c'est quoi ce have_builtin_unreachable au passage ? yen a qui s'éclatent avec le préproc, c'est fou ça grin.gif?14)

__builtin_unreachable (cf. https://gcc.gnu.org/onlinedocs/gcc/Other-Builtins.html#Other-Builtins ) signifie au compilateur que le chemin qui amène à cet appel n'est pas appel.
Typiquement if (n <= 2) __builtin_unreachable (); for(i = 0 ; i < 2; i++)
C'est pratique pour après une instruction asm qui reboote ou pour éliminer des branches de l'arbre de décision du compilateur, qui peut simplifier et prendre le chemin le plus rapide.
(en pratique, ca permet effectivement de générer du code un peu mieux wink)

45

Bon, j'ai écrit cette macro :#define CHECK(condition, label, ...) \ if (!(condition)) { \ fprintf (stderr, "%s, %s, %i\n", __FILE__, __func__, __LINE__); \ #if #__VA_ARGS__ != "" \ fprintf(stderr, __VA_ARGS__); \ #endif /* #__VA_ARGS == "" */ \ goto label; \ }
Elle permet de vérifier un peu comme assert, mais accepte un label où sauter si ça foire, et des arguments à un fprintf (optionnel).

Problème : pas le droit de mettres de #if dans un #define, donc si quelqu'un sait comment contourner ça, ça serait cool...
Au pire, faire un fprintf (""), c'est pas encore trop grave, c'est juste très con. Malheureusement, le préproc C ne supporte pas de ne pas donner d'arguments quand on utilise __VA_ARGS__. C'est faisable en C++ par contre.

Et je veux que ce soit optionnel, parce que ma politique consiste à faire écrire un message sur stdout au moment où l'erreur est levée, et toutes les fonctions appelantes se contentent de constater l'erreur, faire un cleanup et retourner sans rien ajouter. Donc ça permetrait d'utiliser la meme macro partout.

ps -> je sais meme pas si #__VA_ARGS == "" marche, j'ai pas essayé, on verra ça demain grin
ps2 -> ah ben en fait ça marche pas de comparer des strings. sizeof ne marche pas. _Static_assert sait faire, mais renvoie une erreur ><
vous voyez un moyen ?

46

moi j'aime bien les likely() / unlikely() de linux pour optimiser les blocs if

47

Folco (./45) :
vous voyez un moyen ?

Il y a un. Mais je suis fatigué et je vais me coucher.

48

_Static_assert sait faire, mais renvoie une erreur ><
J'y arrive pas non plus avec (?:)

Bon ben à demain alors, bonne nuit grin

49

Tu ne peux pas simplement faire ça :#define CHECK(condition, label, ...) \ if (!(condition)) { \ fprintf(stderr, "%s, %s, %i\n", __FILE__, __func__, __LINE__); \ fprintf(stderr, ##__VA_ARGS__, ""); \ goto label; \ }Ou bien c'est le ##__VA_ARGS__ qui te gêne ? Si tu veux éviter le fprintf(stderr, ""), tu peux ajouter if (*#__VA_ARGS__) devant...
avatar

50

Folco > tu t'es mis à la programmation en macros C uniquement, maintenant ?
avatar
<<< Kernel Extremis©®™ >>> et Inventeur de la différence administratif/judiciaire ! (©Yoshi Noir)

<Vertyos> un poil plus mais elle suce bien quand même la mienne ^^
<Sabrina`> tinkiete flan c juste qu'ils sont jaloux que je te trouve aussi appétissant

51

oui apres la programmation fonctionnelle, il essaye la programmation macronelle.

52

grin
avatar
<<< Kernel Extremis©®™ >>> et Inventeur de la différence administratif/judiciaire ! (©Yoshi Noir)

<Vertyos> un poil plus mais elle suce bien quand même la mienne ^^
<Sabrina`> tinkiete flan c juste qu'ils sont jaloux que je te trouve aussi appétissant

53

Je sais pas ce que je fais, mais j'ai passé ma soirée dans la doc de GCC et sur stackoverflow, et j'essaye de trouver des solutions à mes problèmes. Comme d'hab ça galère, mais je finirai bien par trouver qqchose ^^

54

Et ensuite, tu chercheras des problèmes à tes solutions hehe
avatar
<<< Kernel Extremis©®™ >>> et Inventeur de la différence administratif/judiciaire ! (©Yoshi Noir)

<Vertyos> un poil plus mais elle suce bien quand même la mienne ^^
<Sabrina`> tinkiete flan c juste qu'ils sont jaloux que je te trouve aussi appétissant

55

RHJPP -> il marche comment le ##__VA_ARGS__ ?
Si j'en crois mes essais :
#include <stdio.h>
#include <stdbool.h>

#define CHECK(condition, label, ...)                                  \
  if (!(condition)) {                                                 \
    fprintf(stderr, "%s, %s, %i\n", __FILE__, __func__, __LINE__);    \
    fprintf(stderr, ##__VA_ARGS__, "");                               \
    goto label;                                                       \
  }

int main (int argc, char** argv)
{
  CHECK (false, pouet, "pwic\n")

    pouet:
  return 1;
}

Ca marche quand je compile : folco@Foch:~$ gcc -std=c11 test.c -o test
Mais je comprends pas, pourquoi ## et non # ? Je voulais juste stringifier, pourtant je vois bien ce qui se passe :
gcc -E test.c
avec # : if (!(0)) { fprintf(stderr, "%s, %s, %i\n", "test.c", __func__, 13); fprintf(stderr, "\"pwic\n\"", ""); goto pouet;
avec ## : if (!(0)) { fprintf(stderr, "%s, %s, %i\n", "test.c", __func__, 13); fprintf(stderr, "pwic\n", ""); goto pouet;

Donc j'ai bien le résultat que je veux, et je t'en remercie, mais je comprends pas la coup du ## triso Pour moi, ça "stringifiais" des symboles, ça les concaténait, puis ça les déstringifiait pour en refaire un symbole, comme ici : https://gcc.gnu.org/onlinedocs/cpp/Concatenation.html#Concatenation
Je croyais comprendre que ## prend un symbole de chaque coté en argument, ce qui n'est pas le cas ici.
=> En fait, je ne vois pas du tout l'intérêt du ## ici, j'ai l'impression que j'ai la meme sortie en passant directement __VA_ARGS__

En tout cas, merci encore, parce que "ça marche" ! grin

56

flanker (./54) :
Et ensuite, tu chercheras des problèmes à tes solutions hehe

Ben oui, comment pourrais-je chercher des solutions à mes problèmes si je ne trouve pas de problème à mes solutions ? Faut un peu de bonne volonté quand on programme, que diable embarrassed

57

le ## en general il sert a la concatenation de tokens

genre

#define prefix plop
#define funcname(suffix) prefix ## suffix

funcname(boo) fera plopboo

c'est le seul moyen de coller 2 arguments de macro.

MAIS avec __VA_ARGS__ il a un role special:

http://gcc.gnu.org/onlinedocs/cpp/Variadic-Macros.html

Normalement tu veux ecrire comme ca:

You can have named arguments as well as variable arguments in a variadic macro. We could define eprintf like this, instead:

#define eprintf(format, ...) fprintf (stderr, format, __VA_ARGS__)

MAIS grosse contrainte, VA_ARGS peut pas etre vide:

unfortunately it is less flexible: you must now supply at least one argument after the format string.

Oblige d'avoir un argument. Donc pour contourner:

the ‘##’ token paste operator has a special meaning when placed between a comma and a variable argument. If you write

#define eprintf(format, ...) fprintf (stderr, format, ##__VA_ARGS__)

and the variable argument is left out when the eprintf macro is used, then the comma before the ‘##’ will be deleted.

Donc ##__VA_ARGS__ sert a virer la virgule qui te fait chier quand y'a pas de VA_ARGS grin

ta macro n'est donc toujours pas bonne. Ce que tu veux, c'est ca:

#define CHECK(condition, label, fmt, ...)                                  \
  if (!(condition)) {                                                 \
    fprintf(stderr, "%s, %s, %i\n", __FILE__, __func__, __LINE__);    \
    fprintf(stderr, fmt, ##__VA_ARGS__);                               \
    goto label;                                                       \
  }


et ca s'utilise:

CHECK(pernawel, pluzungoss, "la mere nawel est triste");
CHECK(pernawel, pluzungoss, "la mere nawel est triste, il est parti depuis %d jours", jours);

58

Folco (./55) :
=> En fait, je ne vois pas du tout l'intérêt du ## ici, j'ai l'impression que j'ai la meme sortie en passant directement __VA_ARGS__

sauf quand ya pas d'argument connard, apprends à réfléchir bordel §!!ùù vtff

59

Purée merci squalyl, je l'ai lue au moins deux fois hier soir cette page, et j'ai déjà oublié ><
Et je viens de me rendre compte que sans argument, j'ai en effet une virgule en trop ><
Féchier d'etre con des fois cry

Par contre, je crois qu'avec le trick de RHJPP (le "" en fin de liste d'arguments de fprintf), pas besoin de passer de format, ce qui est bien ce que je veux dans ma macro : passer une chaine si je veux echo qqchose, sinon ne rien passer du tout, auquel cas c'est le "" qui sert de format. Enfin, si j'ai bien compris grin

Merci en tout cas. smile

60

C'est surtout la syntaxe qui est un peu moisie..
avatar
Proud to be CAKE©®™


GCC4TI importe qui a problème en Autriche, pour l'UE plus et une encore de correspours nucléaire, ce n'est pas ytre d'instérier. L'état très même contraire, toujours reconstruire un pouvoir une choyer d'aucrée de compris le plus mite de genre, ce n'est pas moins)
Stalin est l'élection de la langie.