• STATISTIQUES
  • Il y a eu un total de 0 membres et 30809 visiteurs sur le site dans les dernières 24h pour un total de 30 809 personnes!
    Membres: 2 605
    Discussions: 3 579
    Messages: 32 816
    Tutoriels: 78
    Téléchargements: 38
    Sites dans l'annuaire: 58


  • ANNUAIRE
  • [FR] Newbie Contest
    Crackme: 35, Cryptographie: 49, Hacking: 27, Javascript/Java: 17, Logique: 31, Programmation: 23, Stéganographie: 53
    Challenges
    [EN] Hack This Site
    Hack This Site est considéré comme un réel terrain d'entraînement légal pour le...
    Hacking
    [FR] Developpez.net
    Un forum communautaire qui se veut pour les développeurs en générale. Avec presque 500 000 membr...
    Programmation
    [FR] Hackfest
    Le Hackfest est un évènement de sécurité et de piratage informatique au Québec reg...
    Hacking
    [FR] µContest
    µContest est un site de challenges de programmation, c'est à dire qu'il propose des épreu...
    Hacking
    [EN] Rankk
    Site de challenge construit sur le principe d'une pyramide à 9 level. Level 1: 60,Level 2: 72,Level 3: 68,Lev...
    Challenges
    [FR] Zenk-Security
    La communauté zenk-security a pour objet principal la sécurité informatique, nous sommes des tou...
    Hacking

  • DONATION
  • Si vous avez trouvé ce site internet utile, nous vous invitons à nous faire un don du montant de votre choix via Paypal. Ce don servira à financer notre hébergement.

    MERCI!




Note de ce sujet :
  • Moyenne : 0 (0 vote(s))
  • 1
  • 2
  • 3
  • 4
  • 5
[C] Local Computation
21-08-2014, 17h18 (Modification du message : 21-08-2014, 17h30 par octarin.)
Message : #1
octarin Hors ligne
Apprenti sorcier
*



Messages : 68
Sujets : 11
Points: 47
Inscription : May 2013
[C] Local Computation
J'ai découvert cette fonctionnalité du C permettant de récupérer le résultat d'un algorithme autrement que par une fonction. Cela sert (selon moi) à clarifier le code.

Voici un exemple avec la suite de fibonacci.
Code C :

#include <stdio.h>

int main(void)
{
    int lim = 6;
    int nb;

    nb = ({
            int a, b, i;
            b = 1 + (a = 0);
            while (lim--) {
                b = a + b;
                a = b - a;
            }

            b = b;
            });

    printf("Le %de nombre de la suite de fibonacci est %d\n", lim, nb);

    return 0;
}
 


Edit: Cela semble particulièrement utile dans une macro

Code C :

#include <stdio.h>

#define fibonacci(l) ({
            int a, b, i, lim = l; \
            b = 1 + (a = 0); \
            while (lim--) { \
                b = a + b; \
                a = b - a; \
            } \

            b = b; \
            });

int main(void)
{
    int lim = 6;
    int nb;

    nb = fibonacci(lim);
    printf("Le %de nombre de la suite de fibonacci est %d\n", lim, nb);

    return 0;
}
 


Edit2: Bon, si quelqu'un trouve le moyen de le faire marcher dans une macro...
Faire des mathématiques c’est donner le même nom à des choses différentes. -- Henri Poincaré
+1 (1) -1 (0) Répondre
22-08-2014, 09h54
Message : #2
ark Hors ligne
Psyckomodo!
*****



Messages : 1,033
Sujets : 48
Points: 317
Inscription : Sep 2011
RE: [C] Local Computation
Tiens, je connaissais pas ce truc, intéressant faut voir si c'est vraiment utile par contre, parce que je trouve pas que ça aide a la lisibilité du code, au contraire!
+1 (2) -1 (0) Répondre
22-08-2014, 10h05
Message : #3
Junky Hors ligne
Snorky Master
*



Messages : 228
Sujets : 35
Points: 203
Inscription : Mar 2013
RE: [C] Local Computation
Bonjour,

Moi c'est le 'b = b' que je ne comprends pas trop en faite! :/
Pour la sécurité, sous linux, le principal soucis est l'interface chaise/clavier

+1 (0) -1 (0) Répondre
22-08-2014, 10h25 (Modification du message : 22-08-2014, 10h25 par notfound.)
Message : #4
notfound Hors ligne
#!/usr/bin/env bash
*



Messages : 687
Sujets : 47
Points: 271
Inscription : Sep 2012
RE: [C] Local Computation
(22-08-2014, 10h05)Junky a écrit : Bonjour,

Moi c'est le 'b = b' que je ne comprends pas trop en faite! :/

Imho c'est une erreur de frappe.
Ca doit plutôt être nb=b; sachant qu'il utilise printf("Le %de nombre de la suite de fibonacci est %d\n", lim, nb);
+1 (0) -1 (0) Répondre
22-08-2014, 10h40
Message : #5
Junky Hors ligne
Snorky Master
*



Messages : 228
Sujets : 35
Points: 203
Inscription : Mar 2013
RE: [C] Local Computation
Humm je suis pas sur pour le coup Gros!

Si on regarde son code, le nb est _HORS_ du define. Et de plus le nb == le retour du define. Ou alors je suis passé a côté d'un truc.
Pour la sécurité, sous linux, le principal soucis est l'interface chaise/clavier

+1 (0) -1 (0) Répondre
22-08-2014, 10h48
Message : #6
ark Hors ligne
Psyckomodo!
*****



Messages : 1,033
Sujets : 48
Points: 317
Inscription : Sep 2011
RE: [C] Local Computation
Moi je note quand même qu'il a dit que ca avait pas l'air de marcher dans le define. Donc peut être que c'est une faute.
Après, c'est peut être effectivement une particularité de la syntaxe.
+1 (1) -1 (0) Répondre
22-08-2014, 11h17
Message : #7
notfound Hors ligne
#!/usr/bin/env bash
*



Messages : 687
Sujets : 47
Points: 271
Inscription : Sep 2012
RE: [C] Local Computation
Bon ok. En fait le code est tout pourri.

(J'ai réussi a compiler et exec + avoir le bon résultat, j'finis mon inter et j'poste ça)
Edit en cours...
+1 (0) -1 (0) Répondre
22-08-2014, 11h23
Message : #8
Junky Hors ligne
Snorky Master
*



Messages : 228
Sujets : 35
Points: 203
Inscription : Mar 2013
RE: [C] Local Computation
Fait nous un diff Smile
Pour la sécurité, sous linux, le principal soucis est l'interface chaise/clavier

+1 (0) -1 (0) Répondre
22-08-2014, 11h40 (Modification du message : 22-08-2014, 12h20 par notfound.)
Message : #9
notfound Hors ligne
#!/usr/bin/env bash
*



Messages : 687
Sujets : 47
Points: 271
Inscription : Sep 2012
RE: [C] Local Computation
Chose promise, chose dûe. Comme dit plus haut (post que j'aurai pu éditer si ce vieux c*n de Junky n'avait pas brisé le thread :p) le code est fucked up de partout, même fibo ne marchait pas...
Bref, voici un code qui compile et qui fonctionne :

Code C :

#include <stdio.h>
#define fibonacci(l)({ \
    int i=0, a=0, b=1, s=0 ; \

    while ((l-- - 1)){ s = a + b; a = b; b = s; i++; } \
    nb = b; \
});
int main(void){
    int lim=9;
    int nb;
    nb = fibonacci(lim);
    printf("fib(%d) = %d\n", lim, nb);                                                                                                                                                                                                                                  

    return 0;
}
 


Exec :
Code BASH :

>>> gcc fib_def.c -o OCT ; ./OCT
fib(0) = 34
 


Juste un petit soucis quand je veux afficher fib(<lim>); ça fout 0. J'vous laisse chercher pourquoi.
+1 (3) -1 (0) Répondre
22-08-2014, 12h04
Message : #10
ark Hors ligne
Psyckomodo!
*****



Messages : 1,033
Sujets : 48
Points: 317
Inscription : Sep 2011
RE: [C] Local Computation
(22-08-2014, 11h40)notfound a écrit : Juste un petit soucis quand je veux afficher fib(<lim>); ça fout 0. J'vous laisse chercher pourquoi.

Je sais pas si j'ai bien compris, pour moi, tu veux faire : printf("%d\n", fib(lim));

Si c'est ca, ma réponse serait: parce qu'il y a pas de valeur de retour parce que ça n'est pas une fonction, du coup il print le truc qui est dans RAX, ce qui fout potentiellement la merde ouais.
Accessoirement, en l'état, ca ne compile pas, j'ai été obligé de virer le ';' a la fin de la macro pour pouvoir compiler de cette manière.

Alors du coup, je viens de tester de rajouter ça à la fin de la macro :
Code C :

asm ("movl %0, %%eax"::"r"(nb);
 


Mais lors de la compilation, gcc affiche un message d'erreur comme quoi il ne doit PAS y avoir de valeur de retour.

Ensuite, pour modifier eax un peu indirectement, je me suis dit que je pouvais call une fonction pour faire en sorte qu'elle return la bonne valeur, et comme RAX ne serait pas modifié entre temps, on pourrait le return.
Sauf que la aussi, meme message d'erreur a la compilation.

Pour le coup, ce code fonctionne :
Code C :

#include <stdio.h>

int test(int nb) {
  return nb;
}

#define fibonacci(l)({ \
      int i=0, a=0, b=1, s=0 ;                  \
      while ((l-- - 1)){ s = a + b; a = b; b = s; i++; }    \
      test(b);                          \
    });


int main(void){
  int lim=9;
  int nb;
 
  nb = fibonacci(lim);
  printf("fib(%d) = %d\n", lim, nb);
  return 0;
}
 


En revanche, celui ci ne compiles pas:
Code C :


#include <stdio.h>
#define fibonacci(l)({ \
      int i=0, a=0, b=1, s=0 ;                  \
      while ((l-- - 1)){ s = a + b; a = b; b = s; i++; }    \
      asm ("movl %0, %%eax"::"r"(nb);

    });

int main(void){
  int lim=9;
  int nb;
 
  nb = fibonacci(lim);
  printf("fib(%d) = %d\n", lim, nb);
  return 0;
}
 
+1 (1) -1 (0) Répondre
29-08-2014, 18h27
Message : #11
eax64 Hors ligne
Newbie
*



Messages : 8
Sujets : 0
Points: 13
Inscription : Nov 2012
RE: [C] Local Computation
Plop,
dans la macro, en remplacent
Code C :

nb = b;
 


par
Code C :

b;
 

ça marche et c'est moins moche.

Ce qui donne:

Code C :

#include <stdio.h>
#define fibonacci(l)({ \
    int i=0, a=0, b=1, s=0 ; \
    while ((l-- - 1)){ s = a + b; a = b; b = s; i++; } \
    b; \
})


int main(void){
    int lim=9;
    printf("fib(%d) = %d\n", lim, fibonacci(lim));
    return 0;
}
 
 
+1 (1) -1 (0) Répondre
29-08-2014, 19h14
Message : #12
b0fh Hors ligne
Membre actif
*



Messages : 210
Sujets : 17
Points: 309
Inscription : Jul 2012
RE: [C] Local Computation
Je crois qu'on n'a pas les mêmes critères de lisibilité Smile Ce type de gadget peut dysfonctionner de manière subtile et non-intuitive (je me demande combien ici ont vraiment testé ce code...) par exemple:

Code C :
for(lim = 1; lim < 10; ++lim) {
      printf(fibonacci(lim));
   }


ne marchera pas, parce que lim est modifié pendant le contenu de l'appel a fibonacci, un comportement contre-intuitif car impossible avec une fonction classique.

En supposant qu'on corrige la macro pour éviter ça, en faisant une copie de l avant exécution,

Code :
int lim = 1;
while(lim < 10) {
    printf("...", fibonacci(lim++))
}

serait également sémantiquement équivalent à la première boucle si fibonacci était une fonction classique, mais peut donner un truc différent suivant l'implémentation de la macro, si l'argument est évalué plusieurs fois.

De manière générale, les macros en C sont dangereuses et contre-intuitives, sauf si on respecte les contraintes suivantes, plutôt contraignantes:

- parenthèses autour de l'expression top-level
- parenthèses autour de tous les arguments
- évaluation de chaque argument une et une seule fois (et donc pas de boucles avec un argument dans le corps, ou de branches if/else avec un nombre d'appels différents aux arguments dans chaque branche)

Il y a des limitations supplémentaires: comportement bizarre en cas de shadowing, ou d'aliasing de plusieurs arguments, impossibilité de prendre un pointeur vers la fonction...

Les macros sont une relique d'une décennie antérieure. Il n'y en a pas dans les langages modernes. Même C++ s'en était déja largement débarassé au profit d'une alternative type-safe, les templates. Les compilos modernes savent inliner les fonctions courtes.

Conclusion: chaque fois que vous utilisez une macro la ou une alternative existe, Dieu tue un chaton ! alors soyez gentils avec les chatons.
+1 (3) -1 (0) Répondre


Atteindre :


Utilisateur(s) parcourant ce sujet : 4 visiteur(s)
N-PN
Accueil | Challenges | Tutoriels | Téléchargements | Forum | Retourner en haut