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


  • ANNUAIRE
  • [EN] Dare your mind
    JavaScript: 6, Crypto: 44, Stegano: 36, Logic: 13, Special: 27, Science: 11, Realistic: 7, Programming: 10, Crack It: 6,...
    Challenges
    [EN] Listbrain Version 3
    Site proposant 66 challenges présentés dans une liste mélangée.
    Challenges
    [FR] Secuser
    Actualité de la sécurité informatique, fiches virus et hoax, alertes par email, antivirus gratui...
    Hacking
    [FR] Kalkulators
    Ce projet a plusieurs buts, le premier étant l’étude de toutes formes cryptographiques, le cot&ea...
    Cryptographie
    [FR] Le site du zero
    Découvrez gratuitement la programmation (C, C++, PHP, MySQL, XHTML, CSS...), Linux, le Mapping, la modé...
    Programmation
    [EN] SecurityFocus
    SecurityFocus a été conçu pour faciliter la discussion sur des sujets liés la sécu...
    Vulnérabilités
    [FR] Microcontest
    Cryptographie: 7, Mathématiques: 8, Image Son Vidéo: 5, Intelligence artificielle: 3, Réseau: 2, Divers: 7, Phy...
    Challenges

  • 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