Retour à l'accueil
Accueil Aide Rechercher Calendrier Identifiez-vous Inscrivez-vous
Bienvenue, Invité. Veuillez vous connecter ou vous inscrire.
Avez-vous perdu votre courriel d'activation?
17 Juin 2019 à 19:07

Connexion avec identifiant, mot de passe et durée de la session
Règlement | Grades du forum | L'équipe de modération | Album photo | Chat
Rechercher:     avancée
Forums Zelda Solarus  |  Jeux amateurs  |  Programmation  |  Topic: [C] Et pourquoi pas de l'objet ? 0 Membres et 1 Invité sur ce sujet.
Pages: [1] Imprimer
Auteur Sujet: [C] Et pourquoi pas de l'objet ?  (Lu 4449 fois)
Morwenn
Sheikah
*
Offline Offline

Messages: 3 266


And so what?


WWW Courriel
« le: 09 Octobre 2011 à 22:55 »

Ni questions, ni interrogations... Juste une petite histoire sur quelque chose qui m'est arrivé très récemment.

Je suis actuellement en école d'ingénieurs où j'étudie l'informatique. De manière tout à fait étonnante (ou pas), commence l'année en faisant du C. Et arrivé à un moment donné, on doit faire un projet en C. Ce projet doit utiliser des matrices, mais on nous laisse le choix de l'implémentation, soit.

Bien entendu, j'aurais aimé pouvoir utiliser du C++, faire une belle classe, faire des jolies méthodes de classes avec encapsulation des variables et tout et tout. Mais bon, on fait du C, donc pas question de ça... Soit, dans un accès de folie, j'ai quand même essayé de simuler une classe et ses méthodes. Petites explications ci-dessous^^



Une classe matrice en C

Puisqu'on a le choix de l'implémentation de la matrice, j'avais pensé à faire ça :

Code: [Select]
typedef struct
{
    size_t _height;
    size_t _width;
    double* _values;
} Matrix;

Bon, le choix de l'encapsulation à la manière C est déjà fait. Et donc, j'ai dû rajouter quelques méthodes get_height() et get_width() pour récupérer les valeurs. Jusque-là, rien de bien neuf. Sauf que voilà, j'ai toujours envie d'avoir mes méthodes de classes utilisables plus ou moins comme en C++.

Et là, l'illumination !
D'un coup, je décide de partir dans une espèce de code dégueulasse et qui risque de faire pousser des hurlements au professeur et provoquer en lui une vague de doute et d'incompréhension :ninja:



Première étape, on redéfinit notre structure en y ajoutant quelques pointeurs sur fonctions :

Code: [Select]
typedef struct
{
    size_t _width;
    size_t _height;
    double* _values;

    size_t (*get_height)(void);
    size_t (*get_width)(void);

} Matrix;

Juste la base en somme.
Maintenant, reste à utiliser ces pointeurs sur fonctions et quelques directives préprocesseur afin que tout ça ait l'air joli quand on l'utilise, mais si la vérité est plus triste quand on regarde l'implémentation. Voici donc le petit "constructeur" :

Code: [Select]
#define new_matrix(name, y, x) \
    Matrix name;                                     \
    name._height = y;                                \
    name._width = x;                                 \
    name._values = malloc(x * y * sizeof(double));   \
    \
    size_t UNIQUE(get_width, name##x##y)()           \
    {                                                \
        return name._width;                          \
    }                                                \
    name.get_width = &UNIQUE(get_width, name##x##y); \
    \
    size_t UNIQUE(get_height, name##x##y)()          \
    {                                                \
        return name._height;                         \
    }                                                \
    name.get_height = &UNIQUE(get_height, name##x##y);

Pour parvenir à ce résultat, la macro UNIQUE produira un nom de fonction composé du numéro de la ligne d'appel, ainsi que du nom et de la taille de la matrice déclarée. En gros, un nom supposé unique (à part en cas d'utilisation de plusieurs fichiers). Il ne reste plus qu'à attribuer l'adresse de cette fonction unique à un des pointeurs sur fonction de la structure et le tour est joué :D

Voici le code de la macro UNIQUE et des sous-macros utilisées :

Code: [Select]
#define BIND(x, y, ext) x##y##ext
#define UNIQUE_(name, x, ext) BIND(name##_, x, ext)
#define UNIQUE(name, ext) UNIQUE_(name, __LINE__, ext)


Sensiblement immonde me direz-vous, mais tellement agréable à utiliser après^^

Code: [Select]
int main()
{
    new_matrix(M, 5, 6);
    new_matrix(N, 2, 3); new_matrix(P, 5, 4);

    size_t a = P.get_height();

    printf("%d ", M.get_width()); printf("%d\n", M.get_height());
    printf("%d\n", N.get_width());

    return EXIT_SUCCESS;
}

Bref, je m'étonne toujours de ce qu'on peut faire en C. Probablement pas toujours pour le meilleur x)
« Dernière édition: 09 Octobre 2011 à 23:19 par Guillaume » Journalisée

Noxneo
Guest


Courriel
« Répondre #1 le: 09 Octobre 2011 à 23:16 »

Argh non tu n'as rien compris, et si Kernighan ou Ritchie te voyaient ils te donneraient une fessée.

Oui, il est possible de faire "de l'objet en C" via des truchements comme ceux que tu as présentés. Il est aussi possible d'écrire un interpréteur de langage fonctionnel (appellons le MorwennLambda) et de faire ton projet en écrivant des scripts MorwennLambda. Après tout, pourquoi pas ? Tu réponds à la question, ton projet fais ce qu'il est censé faire, et tu démontres une connaissance du langage bcp plus approfondie que celle de tous tes camarades.
D'ailleurs, si tu regardes ce que produit un compilateur C++, tu réaliseras qu'au final il fait plus ou moins ce que tu as écris.

Pourtant, c'est être complètement à côté de la plaque. Le C est un langage avec ses propres idiomes, sa propre philosophie, etc. qui est fait pour répondre à une certaine catégories de problèmes. Là tu outrepasses tout ça (en faisant du code super moche au passage- ta macro unique me donne envie de recracher tous mes repas des 3 dernières semaines) alors que si tu allais dans le sens du C, tout irait beaucoup mieux.

Oui, on peut enfoncer un clou avec un préservatif, mais c'est pas le meilleur moyen.

EDIT: sans compter qu'au final tu as un truc super bâtard orienté objet mais pas vraiment. Quid de l'héritage? Des variables privées vs. protégées vs. public? Des classes amies? Du polymorphisme?
Au passage tu n'es pas le premier à tenter ça, c'est un petit exercice intéressant en soi mais qui relève du blasphème pour du code de production. (lien)

Bref, je m'étonne toujours de ce qu'on peut faire en C. Probablement pas toujours pour le meilleur x)

Ah ben oui ça c'est sûr, tu peux faire ce que tu veux et sa grand mère en C ^^
« Dernière édition: 09 Octobre 2011 à 23:19 par Guillaume » Journalisée
Morwenn
Sheikah
*
Offline Offline

Messages: 3 266


And so what?


WWW Courriel
« Répondre #2 le: 09 Octobre 2011 à 23:29 »

Pourtant, c'est être complètement à côté de la plaque. Le C est un langage avec ses propres idiomes, sa propre philosophie, etc. qui est fait pour répondre à une certaine catégories de problèmes.

Oui, c'est aussi ce que j'aimerais répondre à mon prof de temps à autres quand il demande de faire de la programmation générique en C de manière plus ou moins illisible (Quoique le C1X pourra y apporter une solution un brin plus élégante, mais je le soupçonne de ne jamais avoir utilisé le C99, donc bon...)^^

Donc bon, quand on voit qu'il nous demande de faire de plus en plus de trucs pour lesquels ne sont pas faits le C, j'en venais à vrai dire à me demander ce que ça donnerait si on poussait plus loin encore ce principe... Ne t'en fais donc pas, je suis tout à fait conscient des idiomes du C lorsque je passe au-dessus (à vrai dire, pour certains trucs demandés, je meurs d'envie d'utiliser du C++, mais on n'a pas le droit).

Ton lien est intéressant en tout cas, le gars a dû y passer pas mal de temps, c'est impressionnant :blink:
Journalisée

Noxneo
Guest


Courriel
« Répondre #3 le: 09 Octobre 2011 à 23:31 »

Je viens de réaliser que mon post semble sans doute très critique envers ce que tu as fait ^^ En fait pas du tout, c'est un très bon exercice de style et c'est marrant et instructif de voir comment on peut casser les conventions des langages.

Juste que si j'étais prof et qu'un élève me rendait un devoir comme ça (ou que l'un de mes employés écrivait du code de production comme ça), ça passerait pas :D Après si le prof vous demande de faire du n'importe quoi en C, c'est de sa faute :ninja:

Bon sinon à chaque fois que je relis ça...
Code: [Select]
#define BIND(x, y, ext) x##y##ext
#define UNIQUE_(name, x, ext) BIND(name##_, x, ext)
#define UNIQUE(name, ext) UNIQUE_(name, __LINE__, ext)

Journalisée
Wouf
Hylien
*
Offline Offline

Messages: 1 116


C'est la faim !


Courriel
« Répondre #4 le: 09 Octobre 2011 à 23:33 »

Bah, moyennant casts, tu peux faire bcp de choses :
- faire de l'héritage en c
- casser l'encapsulation en c++
- ...

Tu peux aller voir les tutos sur developpez.com si ça t'intéresse. :)
Après, tu peux aussi voir le projet Gnome, avec gLib et gObject qui permettent l'oo en C. Sans oublier Vala, suite logique puisqu'il s'agit d'un langage oo qui compile en C/gObject.

Sinon, je suis d'accord avec Guillaume, ça devrait rester du joujou/expérimentation/apprentissage ^_^
Journalisée

Marre des pavés ? Marchez dans la boue!
ハハ、あなたは私の罠に落ちた!
Morwenn
Sheikah
*
Offline Offline

Messages: 3 266


And so what?


WWW Courriel
« Répondre #5 le: 09 Octobre 2011 à 23:39 »

Je ne savais pas qu'il y avait autant de projets pour faire de la prog objet en C, je pensais aussi que ça restait toujours au stade de la simple expérimentation, faudra que je jette un coup d’œil :P

Bon sinon à chaque fois que je relis ça...
Code: [Select]
#define BIND(x, y, ext) x##y##ext
#define UNIQUE_(name, x, ext) BIND(name##_, x, ext)
#define UNIQUE(name, ext) UNIQUE_(name, __LINE__, ext)



Ouais, à priori, sans avoir tous ces niveaux de macros les uns au-dessus des autres, tout ce que va me faire mon préprocesseur, c'est par exemple pour UNIQUE(nom, fin) me ressortir nom____LINE__fin au lieu de nom_5fin si __LINE__ correspond à la ligne 5. Ça fait partie des trucs les moins instinctifs je trouve.
Journalisée

Noxneo
Guest


Courriel
« Répondre #6 le: 10 Octobre 2011 à 00:13 »

Je ne savais pas qu'il y avait autant de projets pour faire de la prog objet en C, je pensais aussi que ça restait toujours au stade de la simple expérimentation, faudra que je jette un coup d’œil :P


http://en.wikipedia.org/wiki/Objective-C

:P
Journalisée
Morwenn
Sheikah
*
Offline Offline

Messages: 3 266


And so what?


WWW Courriel
« Répondre #7 le: 10 Octobre 2011 à 00:15 »

Ah oui, mais là, on change carrément de langage pour passer à la prog objet :P

En parlant des évolutions du C, j'aurais bien envie d'essayer le D un de ces jours, mais son problème de bibliothèque standard semble être quelque peu gênant quand même :/
Journalisée

Noxneo
Guest


Courriel
« Répondre #8 le: 10 Octobre 2011 à 00:40 »

Non justement, l'objective-C est du C avec une surcouche qui ajoute du messaging et qui fait du binding dynamique en runtime (ouhlà Papy39 va nous faire une attaque cardiaque en lisant ça!)

Jamais testé le D, mais il parait que c'est sympa. Si je ne m'abuse Kenta Cho a fait tout ses jeux avec.
Journalisée
yoshi04
Conseiller J-A
Sheikah
*
Offline Offline

Messages: 3 625


I can't hug every cat


WWW Courriel
« Répondre #9 le: 10 Octobre 2011 à 01:10 »

Actuellement je bosse plus ou moins sur du code source de VLC, qui est écrit en C et dont la partie libVLCcore est en "orienté-objet".

Plus d'infos sur le wiki officiel.

(la doc reste très générale je préviens).

Le langage C n'est vraisemblablement pas conçu pour être facilement adapté au paradigme objet. Ceci dit il est tout à fait possible de détourner de nombreuses choses pour arriver à ses fins et ce n'est clairement pas toujours la meilleure solution...

Bref comme l'ont dit les autres, ok c'est fun mais rend pas ça à ton prof  :P

(et pour les casts dégueulasses, demander à chris  :ninja:)
Journalisée
Noxneo
Guest


Courriel
« Répondre #10 le: 10 Octobre 2011 à 01:48 »

Quote
vlc_object_create() - create an object and set its refcount to 0
vlc_object_destroy() - de-allocate an object iff its refcount = 0
vlc_object_attach() - bidirectionally link an object with its parent
vlc_object_detach() - remove all links between an object and its parent

Journalisée
BenObiWan
Ancien
Sheikah
*
Offline Offline

Messages: 3 382



Courriel
« Répondre #11 le: 10 Octobre 2011 à 10:47 »

:o
On dirait qu'il y a des gens qui ne comprennent pas que chaque langage à ses avantages et inconvénients, et que pousser aux limites c'est juste faire du code impossible à relire :o
Journalisée

Quote
Ash Nazg Durbatulùk, Ash Nazg Gimbatul,
Ash Nazg Thrakatulùk agh bruzum-ishi krimpatul.
The fellowship of the Ring - J.R.R. Tolkien
Noxneo
Guest


Courriel
« Répondre #12 le: 10 Octobre 2011 à 10:58 »

pousser aux limites c'est juste faire du code impossible à relire :o

Mais tellement fun à écrire ! :D Ça doit bien compter pour quelque chose?
Journalisée
BenObiWan
Ancien
Sheikah
*
Offline Offline

Messages: 3 382



Courriel
« Répondre #13 le: 10 Octobre 2011 à 11:05 »

Bah pour faire des petits trucs comme Morwenn pourquoi pas, mais pour un projet comme VLC... WTF?
Journalisée

Quote
Ash Nazg Durbatulùk, Ash Nazg Gimbatul,
Ash Nazg Thrakatulùk agh bruzum-ishi krimpatul.
The fellowship of the Ring - J.R.R. Tolkien
Wouf
Hylien
*
Offline Offline

Messages: 1 116


C'est la faim !


Courriel
« Répondre #14 le: 10 Octobre 2011 à 12:54 »

S'il était écrit en Java, il planterait, ralentirait, fuiterait, ... Bref, je préfère C !
:trollface:
Gnome, le noyau Linux, ... Et beaucoup de librairies sont écrites en C. Pourquoi pas le C++, c'est un autre débat :P

@Morwenn >
Le D, ouais, moi aussi j'ai envie d'essayer quelques petit programmes. Pour le problèmes des 2 libs standards incompatibles, il me semblait que c'était résolu depuis D 2.0, non ? :o
Sinon, c'est clair que ça a freiné l'adoption du langage, malheureusement :/
Journalisée

Marre des pavés ? Marchez dans la boue!
ハハ、あなたは私の罠に落ちた!
Sam101
Sheikah
*
Offline Offline

Messages: 3 721



Courriel
« Répondre #15 le: 10 Octobre 2011 à 16:28 »

Gnome, le noyau Linux, ... Et beaucoup de librairies sont écrites en C. Pourquoi pas le C++, c'est un autre débat :P
Parce que le C++, dès que c'est gros, ça devient souvent horrible à debuguer. En tout cas, beaucoup plus bouffeur de temps qu'en Java par exemple (ou même en C ? Pas essayé.).
Journalisée
Noxneo
Guest


Courriel
« Répondre #16 le: 10 Octobre 2011 à 18:23 »

Parce que le C++, dès que c'est gros, ça devient souvent horrible à debuguer. En tout cas, beaucoup plus bouffeur de temps qu'en Java par exemple (ou même en C ? Pas essayé.).

Mouais, si tu as un bon design, que tu codes de manière défensive (assert et tralalala), le C++ n'est vraiment pas bien pire que le Java ou autre langage. Oui la gestion de la mémoire peut donner du fil à retordre, mais globalement ça dépend juste de la capacité des développeurs à faire attention à ce qu'ils font.
Journalisée
Morwenn
Sheikah
*
Offline Offline

Messages: 3 266


And so what?


WWW Courriel
« Répondre #17 le: 10 Octobre 2011 à 19:54 »

@Morwenn >
Le D, ouais, moi aussi j'ai envie d'essayer quelques petit programmes. Pour le problèmes des 2 libs standards incompatibles, il me semblait que c'était résolu depuis D 2.0, non ? :o
Sinon, c'est clair que ça a freiné l'adoption du langage, malheureusement :/

J'ai entendu dire il me semble qu'ils ont implémenté un système permettant au langage d'utiliser plusieurs librairies standard en même temps (je ne sais pas comment c'était et comment c'est géré). Mais bon, c'est con d'en arriver là pour ça, quoi x)

@Sam : Avec la programmation défensive, on peut en effet faire des debugs assez efficaces. D'autant plus depuis qu'ils ont rajouté les assertions statiques (même si c'était déjà simulable avant) :)
Journalisée

BenObiWan
Ancien
Sheikah
*
Offline Offline

Messages: 3 382



Courriel
« Répondre #18 le: 10 Octobre 2011 à 20:16 »

mais globalement ça dépend juste de la capacité des développeurs à faire attention à ce qu'ils font.

Comme avec tout langage. C'est surtout le développeur qui compte.
Journalisée

Quote
Ash Nazg Durbatulùk, Ash Nazg Gimbatul,
Ash Nazg Thrakatulùk agh bruzum-ishi krimpatul.
The fellowship of the Ring - J.R.R. Tolkien
binbin
Guest


Courriel
« Répondre #19 le: 10 Octobre 2011 à 21:00 »

mais globalement ça dépend juste de la capacité des développeurs à faire attention à ce qu'ils font.

Comme avec tout langage. C'est surtout le développeur qui compte.

+1
Journalisée
Noxneo
Guest


Courriel
« Répondre #20 le: 10 Octobre 2011 à 21:18 »

+1

Faux. Il faut faire un truc du genre:

mutex_write_lock(post);
assert(post!=NULL);
assert(post.points<(MAX_INT-1));
post.points+=1;
mutex_unlock(post);
« Dernière édition: 10 Octobre 2011 à 21:23 par Guillaume » Journalisée
binbin
Guest


Courriel
« Répondre #21 le: 10 Octobre 2011 à 22:00 »

Nox' tu pues :mrgreen:
Journalisée
BenObiWan
Ancien
Sheikah
*
Offline Offline

Messages: 3 382



Courriel
« Répondre #22 le: 10 Octobre 2011 à 22:35 »

Sinon on peut utiliser des structures évolués comme des AtomicInteger ;)
Journalisée

Quote
Ash Nazg Durbatulùk, Ash Nazg Gimbatul,
Ash Nazg Thrakatulùk agh bruzum-ishi krimpatul.
The fellowship of the Ring - J.R.R. Tolkien
Noxneo
Guest


Courriel
« Répondre #23 le: 10 Octobre 2011 à 23:02 »

Le Java c'est caca ©
Journalisée
BenObiWan
Ancien
Sheikah
*
Offline Offline

Messages: 3 382



Courriel
« Répondre #24 le: 11 Octobre 2011 à 06:44 »

C'est marrant comme expérience, "qui sera le premier à comprendre que je parle de Java et crachera dessus?" :D
Journalisée

Quote
Ash Nazg Durbatulùk, Ash Nazg Gimbatul,
Ash Nazg Thrakatulùk agh bruzum-ishi krimpatul.
The fellowship of the Ring - J.R.R. Tolkien
Pages: [1] Imprimer 
Forums Zelda Solarus  |  Jeux amateurs  |  Programmation  |  Topic: [C] Et pourquoi pas de l'objet ?
Aller à:  

Propulsé par MySQL Propulsé par PHP Powered by SMF 2.0.15 | SMF © 2006, Simple Machines LLC XHTML 1.0 Transitionnel valide ! CSS valide !
Zelda Solarus 2009Skin par Eidarloy
Solarus-Games