Obsidian a écrit 5313 commentaires

  • [^] # Re: Enseignement avec des logiciels fossiles, comme d'hab

    Posté par  . En réponse au message Exercice à résoudre !!!. Évalué à 3.

    Ça reste deux choses distinctes. Personne ne t'oblige à utiliser un alias non plus. C'est juste un état de fait.

  • # Quelques indices

    Posté par  . En réponse au message Exercice à résoudre !!!. Évalué à 2.

    Je m'explique, le résultat souhaité consiste à avoir un fichier contenant plusieurs lignes et chaque ligne contient le mot : ouverture ou fermeture / date d'ouverture ou de fermeture / heure d'ouverture ou de fermeture / et si possible l'utilisateur (login) qui s'est connecté.

    Indice : le plus simple pour faire cela est de déposer ton script dans « /etc/init.d » et de créer les liens associés dans /etc/rc0.d, /etc/rc1.d, … /etc/rc6.d.

    Pour ajouter facilement, en shell, une ligne de texte à la fin d'un fichier, regarde du côté de l'opérateur « >> ».

    Renseigne-toi sur « SysVInit », et fais « man bash ». Tu devrais avoir plein d'informations pour commencer, voire même finir car le script shell en question tient en une ou deux lignes maximum.

  • [^] # Re: La Tribune

    Posté par  . En réponse au message Exercice à résoudre !!!. Évalué à 7.

    « Est-ce que vous êtes en train de m'inviter à un dîner de geeks, M. Brochant ? » :-)

  • [^] # Re: Enseignement avec des logiciels fossiles, comme d'hab

    Posté par  . En réponse au message Exercice à résoudre !!!. Évalué à 4.

    Non. Sur la plupart des distributions, « vi » est devenu un alias vers vim. Celui-ci peut alors être lancé en mode compatible mais, souvent, ce n'est même pas le cas.

  • [^] # Re: Le C, toujours autant utilisé

    Posté par  . En réponse à la dépêche Dennis Ritchie, un père d’UNIX, nous a quittés. Évalué à 7.

    Moi, c'est plutôt le contraire. Je n'ai jamais trouvé un logiciel en Java dans le commerce à destination du grand public (je n'ai pas beaucoup cherché non plus, cela dit), et je n'ai jamais travaillé dans un endroit où l'on trouvait du Java sans C — au moins — à côté.

  • [^] # Re: C'est une honte

    Posté par  . En réponse à la dépêche Dennis Ritchie, un père d’UNIX, nous a quittés. Évalué à 3.

    Tu veux dire qu'ils mettaient Steve en quarantaine avec un pull sous sa couverture ?

  • [^] # Re: Relativisons un peu

    Posté par  . En réponse à la dépêche Prix Ig Nobel 2011. Évalué à 2.

    Tu as raison, précisons d'ailleurs que c'est plutôt le rôle des Darwin Award de récompenser les « expériences » les plus stupides et ne devant pas être reproduite.

    Pertinent mais, en principe, les Darwin Awards ne peuvent être attribués, par définition, qu'à titre posthume et ceci limite de beaucoup le champ d'action. Mais je suis d'accord pour dire qu'il faudrait étendre le domaine des Darwin Awards plutôt qu'assigner ça aux IGNobels…

  • [^] # Re: $PATH

    Posté par  . En réponse au message Shell - renseignement. Évalué à 9.

    J'insiste bien sur le point qu'ajouter « ./ » n'est pas une chose à faire. Les cas où tu auras besoin de lancer des exécutables depuis d'autres dépôts que les répertoires par défaut sont limités. Dans ces cas-là, c'est un bon garde-fou que de demander explicitement à les lancer, en utilisant ./ C'est également très répandu dans le monde Unix, donc autant ne pas prendre d'emblée de mauvaises habitudes, surtout si c'est simplement pour reproduire un comportement issu du monde DOS.

  • [^] # Re: lol

    Posté par  . En réponse au journal Ce qui devait arriver Aréva. Évalué à 6.

    D'habitude, j'essaie d'éviter de jouer les grammar nazis mais quand même, de temps en temps, une piqûre de rappel s'impose :

    ils ne se sont pas fait hacker, ils se sont fait défoncer. Nuance :p

    Merci de votre attention, vous pouvez maintenant reprendre une activité normale.

  • [^] # Re: Au temps en emporte le vent

    Posté par  . En réponse au journal Comment se débarrasser des machines en fin de vie ?. Évalué à 3.

    C'est vrai que c'est un fait avéré dans certaines compagnies.

    Mais en l'occurrence, ce n'était pas le cas. On voit toujours des gens faire les encombrants comme on fait les brocantes et, ces dernières années, on a vu beaucoup de ferrailleurs. J'ai déposé un grand four en fin de vie (plus de 30 ans) et il a disparu avant la cinquième minute.

    Mais la récup' de câbles et d'ustensiles en métal, au dépit du reste, est quelque chose qui a été flagrant ces trois dernières années. Dans le cas qui nous concerne, on se tenait encore près du tas lorsque le type, affable, est arrivé dans son pickup. Il nous a gentiment demandé s'il pouvait se servir. J'étais trop heureux de voir quelqu'un récupérer mon moniteur avant qu'il prenne la pluie, jusqu'à ce qu'il le sacrifiasse d'un coup de tenaille. Mais il est bien reparti avec le bout de câble, qui est d'ailleurs allé rejoindre le reste de sa collection.

  • [^] # Re: rename et les regexp

    Posté par  . En réponse au message Renommer plusieurs fichiers en même temps. Évalué à 2.

    Sache toutefois que, sous Unix, tout ou presque est case-sensitive. Tu dois donc respecter majuscules et minuscules mais pas d'inquiétude : en général, tout est écrit en minuscules.

  • [^] # Re: Au temps en emporte le vent

    Posté par  . En réponse au journal Comment se débarrasser des machines en fin de vie ?. Évalué à 3.

    Moi je l'ai fait aussi. Au passage des encombrants, j'ai reformé un vieux PII/350Mhz avec un moniteur cathodique un peu trop encombrant pour moi, mais qui marchait très bien et que j'avais soigné toutes ces années durant. Je l'ai déposé la veille en espérant que quelqu'un le récupère.

    Un ferrailleur est arrivé, il a sectionné à ras le câble VGA avec une taille (pour en récupérer le cuivre, j'imagine), est reparti avec et a laissé là le reste du moniteur, désormais inutilisable :-(

    Bon, depuis, le problème a été résolu : les encombrants ne passent plus chez moi.

  • [^] # Re: Titre

    Posté par  . En réponse au journal « Les USA viennent donc de légaliser le vol. ». Évalué à 3.

    C'est déjà comme ça depuis longtemps. Edison, par exemple, a fini par être réputé pour cela. Il faut prouver l'antériorité pour invalider le brevet.

    Si tu dis simplement « j'en ai parlé à mon pote », ben tu l'as effectivement dans le baba (pourquoi t'en as parlé à ton pote, aussi ?). En plus, sans être un expert, j'imagine que l'antériorité ne doit pas seulement être établie, il doit aussi falloir que l'invention ait été rendue publique.

  • [^] # Re: Venezuela

    Posté par  . En réponse au journal Microsoft, Tunisie et logiciel libre. Évalué à 9.

    J'avais lu « sur le vuvuzela » au début… Ça aurait expliqué bien des choses !

  • [^] # Re: C'est dd qui merde

    Posté par  . En réponse au message cat et dd. Évalué à 4.

    Les pipes sont bien bloquants… s'il n'y a rien à lire dedans ! Mais si on fait un appel read() dessus en passant la taille d'un buffer par exemple et qu'il y a bien des caractères disponibles mais qu'il n'y a pas le compte, alors l'appel va ressortir en renvoyant le nombre de caractères qu'il a réussi à lire.

    Lorsqu'on exploite directement le disque ou un fichier, la question ne se pose pas. Les caractères sont forcément disponibles et c'est directement dd (ou n'importe quel programme à sa place) qui va aller chercher les données, par l'intermédiaire du pilote. Il n'y a qu'en cas de fin de fichier ou d'erreur que le bloc à lire peut être incomplet.

    Par contre, dans le cas d'un pipe, c'est entièrement au bon vouloir du processus écrivain qui, par définition, a un comportement asynchrone et versatile.

  • [^] # Re: À vue de nez…

    Posté par  . En réponse au message cat et dd. Évalué à 1.

    Je retire le point numéro 2. J'ai confondu « seek » et « skip ».

  • # À vue de nez…

    Posté par  . En réponse au message cat et dd. Évalué à 3.

    1. Pourquoi utilises-tu trois « cat » successifs dans un bloc ? « cat » signifie « catenate » et sert justement à concaténer plusieurs fichiers. Utilise plutôt « cat fichier1 fichier2 fichier3 » et vire les parenthèses ;

    2. Si tu lis tes données depuis l'entrée standard, il faut enlever les clauses « seek ». Tu ne relis pas, à chaque fois, le même fichier depuis le début, tu lis les données qui te parviennent les unes après les autres. Le début de ton fichier a donc déjà été « consommé » par les commandes « dd » précédentes.

  • [^] # Re: L'hôpital se fout de la charité…

    Posté par  . En réponse au message Alternative fiable à Firefox sous Windows. Évalué à 2.

    Question bête : qu'est-ce que tu utilises pour accéder à tes serveur Unix ? J'imagine que c'est déjà le cas mais, autrement, un serveur X pour accéder à une session XDMCP ne serait-elle pas la solution pour avoir la paix ?

    Il fut un temps, dans un métier antérieur, où l'on n'utilisait que des thin clients pour se connecter à des serveurs de travail, lesquels étaient sous Windows, sous Solaris ou sous Linux. Bien que ceux-ci reconnaissent les principaux protocoles de tous les serveurs, il était parfois plus efficace de se connecter à un Linux et d'y ouvrir un rdesktop vers les serveurs Windows. Malgré les relais successifs, c'était plus fluide :-)

  • [^] # Re: L'hôpital se fout de la charité…

    Posté par  . En réponse au message Alternative fiable à Firefox sous Windows. Évalué à 2.

    Je n'ai qu'un mot : pauvre abruti.

    Reconnais que ça ne donne pas vraiment envie de t'aider (et qu'en plus, ça fait deux mots).

    Alors c'est vrai, tu me répondras que j'ai choisi mon taf, mais d'un autre côté, l'OS que j'utilise au quotidien pour accéder à mon environnement de travail n'est pas le plus important dans mon travail. Et mon poste actuel me permettra de gagner en compétences et en crédibilité, pour pouvoir à l'avenir je l'espère, me passer d'un environnement windows pour effectuer mes taches quotidiennes.

    J'espère simplement que tu t'épanouis dans ton poste sur d'autres points ou qu'à tout le moins, tu y trouves ton compte. Parce qu'autrement, je ne sais pas où tu habites, mais les postes sous Linux sont quand même beaucoup plus courants qu'on ne le croit. Là où je travaille, on m'a filé un poste vide et on m'a laissé le choix de l'O.S. (Windows compris, avec licence). J'y ai mis une Fedora 15.

    C'est très bien d'essayer de faire carrière et de trimer dur pour espérer aboutir à la situation qui te plaît, mais l'expérience m'a montré que 1) la vie est courte ; 2) la carrière l'est encore plus ; 3) Personne ne va t'orienter à ta place si tu ne pèses pas de toute ta personne pour aller où tu veux. Bouffer des technos que l'on n'aime pas, c'est bien quand c'est alimentaire. Pour le reste, il est si rare d'avoir des opportunités dan le monde du travail que c'est presque criminel de ne pas en profiter quand elles se présentent. :-)

    Le piège absolu quand on est orienté Linux étant les S.S.I.I. Quand on a passé deux ans à se faire dire telle mission est sous NT4 (à l'époque) mais que la prochaine sera sous Unix, garanti ! et qu'on a fait ça sept fois de suite, on comprend vite que ces compagnies ne se font pas d'argent avec des systèmes qui fonctionnent.

  • # Opera

    Posté par  . En réponse au message Alternative fiable à Firefox sous Windows. Évalué à 1.

    Opera

    http://www.opera.com/

    Fonctionne aussi bien sous Windows que sous Linux. Si tu ne connais pas déjà, si tu ne peux utiliser Firefox et qu'il n'est évidemment pas question de repasser à I.E., je pense que tu seras vite « Konqui » :-)

  • [^] # Re: Merci beaucoup à vous, j'ai tout compris !

    Posté par  . En réponse au message L'opérateur unaire * me laisse perplexe (pointeurs sur fonctions principalement). Évalué à 2.

    //cool qu'on puisse dé-référencer sans étoile

    Oui, et si c'est le cas, ça fonctionne aussi dans l'autre sens. Ces deux expressions sont équivalentes s'il s'agit d'une fonction :

    ptr_g = &g;
    ptr_g = g;
    
    

    J'ai toujours un avertissement que je ne comprend pas, concernant la ligne return a(); :
    attention : ‘return’ with a value, in function returning void [enabled by default]
    a() ne retourne pas void puis-ce qu'il est de type int (*) (void)…

    Non, mais ta fonction main(), elle, est déclarée « void main (void) ». Ce qui gène alors le compilo, c'est justement le fait que tu renvoies un int.

  • # Grammaire C

    Posté par  . En réponse au message L'opérateur unaire * me laisse perplexe (pointeurs sur fonctions principalement). Évalué à 2.

    Je rajoute un commentaire pour préciser que la norme C spécifie et détaille la grammaire formelle du langage (tant et si bien qu'en théorie, on pourrait presque la balancer directement à Lex & Yacc pour recompiler un compilateur, ce qui est précisément la définition de « Y.A.C.C. »).

    Et en ce qui concerne les types en particulier, ceux-ci font l'objet d'une section dédiée : 6.7.6

    6.7.6 Type names
    
    type-name:
        specifier-qualifier-list abstract-declaratoropt
    abstract-declarator:
         pointer
         pointeropt direct-abstract-declarator
    direct-abstract-declarator:
        ( abstract-declarator )
        direct-abstract-declaratoropt [ type-qualifier-listopt assignment-expressionopt ]
        direct-abstract-declaratoropt [ static type-qualifier-listopt assignment-expression ]
        direct-abstract-declaratoropt [ type-qualifier-list static assignment-expression ]
        direct-abstract-declaratoropt [ * ]
        direct-abstract-declaratoropt ( parameter-type-listopt )
    
    

    Les « opt » en fin de noms de règles sont en fait écrits en indice dans le document PDF. Donc, ici, « pointer » et « pointeropt » sont la même règle.

    On voit, comme c'est l'usage dans la définition de telles grammaires, que les différentes règles font massivement références à elles-mêmes, d'où la récursivité. C'est ce qui te permet de construire des types de plus en plus compliqués, en partant du centre comme expliqué dans nos commentaires précédents.

  • [^] # Re: Parsing en C

    Posté par  . En réponse au message L'opérateur unaire * me laisse perplexe (pointeurs sur fonctions principalement). Évalué à 2.

    Hello,

    Cependant, il y a encore des choses qui m'échappent. Tu dis « Tu poses (éventuellement) un >identifiant »
    Ne pas mettre l'identifiant sert à donner le type de retours d'une fonction par exemple ?
    dans l'exemple
    int f(int)(void);

    C'est un exemple qui ne fonctionnera pas. Le compilo ne te laissera pas faire. Par contre, il te dira quand même « erreur: ‘f’ declared as function returning a function », ce qui montre que notre syntaxe était correcte sur le plan formel.

    on peut dire que le retour de f est de type int (void) ? Par exemple, imaginons une fonction qui retourne un pointeur vers une fonction int (g)(void) mais sous forme d'un pointeur (void *) comme le ferait un thread par exemple, il est possible de caster ce pointeur avec ( int ()(void) ) ?

    N'oublie pas que tu retournes un pointeur ! Il faut donc le caster vers un « pointeur sur une fonction n'admettant aucun argument, mais retournant un int ». Donc « (int(*)(void)) ». Ça, oui, c'est possible. Tu peux même l'invoquer directement en ajoutant des paramètres entre parenthèses à la suite de ton appel à « f », ce qui donne une syntaxe toute particulière. :-)

    Je trouve que les pointeurs vers des fonctions font 4 octets (quelle qu'elles soient), et que les fonctions n'en font qu'un (d'ailleurs, on est limité à 256 types de fonctions ?)

    Il est probable (c'est à vérifier) que dans ce cas précis, le compilateur utilise un mécanisme similaire aux énumérations pour cataloguer tes définitions de type de fonction. Ces énumérations sont réputées être codé sur un type entier de n'importe quelle taille (donc y compris char). Les membres eux-mêmes devant pouvoir être convertis en int.

    j'ai l'impression d'être complètement à coté de la plaque. Je crois qu'il faut vraiment que j'apprenne des bases d'assembleur.

    C'est toujours une bonne chose de le faire, et ça t'aidera beaucoup dans la compréhension du C et des systèmes informatiques en général. Par contre, dans ce cas précis, ça ne te sera d'aucune utilité.

  • [^] # Re: Parsing en C

    Posté par  . En réponse au message L'opérateur unaire * me laisse perplexe (pointeurs sur fonctions principalement). Évalué à 2.

    UPDATE: J'ai des crochets qui ont disparu dans la déclaration de « tableau ». Je la refais :

    1. tableau
    2. tableau[]
    3. (* tableau[])
    4. (* tableau[])()
    5. int (* tableau[])()
  • # Parsing en C

    Posté par  . En réponse au message L'opérateur unaire * me laisse perplexe (pointeurs sur fonctions principalement). Évalué à 4.

    là, l'opérateur s'applique à ce qu'il y a à sa droite :
    int * ptr_sur_entier,entier; // déclare un pointeur sur int, et un int, donc c'est équivalent à :
    int (*ptr_sur_entier),entier;

    En fait, ça s'applique bien à gauche mais… une seule fois. :-) C'est dû au fait que contrairement aux autres spécificateurs de type, tu peux enchaîner les pointeurs sur une longueur arbitraire. Ainsi :

    typedef char *** montype;
    montype **a, *b;

    … te donnera respectivement « char ***** a » et « char **** b ». L'opérateur « * » sert donc bien à définir un type, mais est un non-terminal.

    Pour le reste, tout devient plus clair lorsque l'on admet qu'un type est défini de manière récursive, comme lorsque tu développes une expression mathématique en commençant par les parenthèses les plus imbriquées, celles-ci pouvant se trouver au centre de l'expression et pas forcément sur les côtés.

    Un type en lui-même pourrait être défini de n'importe quelle manière mais que, dans les faits, il se trouve généralement à gauche de l'identifiant auquel il est ÉVENTUELLEMENT associé, sauf dans deux cas : les déclarations de fonctions et les déclarations de tableaux, qui se représentent respectivement avec () et [], lesquels prennent place à droite de l'identifiant. Donc, dans l'ordre :

    1. Tu poses (éventuellement) un identifiant. Le nom de ton instance ;
    2. Tu le fais suivre au choix par

    — Rien (instance ordinaire)
    — Une paire de parenthèses (fonction), à l'intérieur desquelles tu vas parser… des noms de types éventuellement nommés (les paramètres), exactement comme tu es actuellement en train de le faire. Récursivement, donc.
    — Une paire de crochets (tableau) contenant une taille éventuelle.

    1. Tu fais précéder soit par rien, soit par une une étoile pour indiquer que l'expression ENTIÈRE décrite jusqu'ici est un pointeur et non l'élément final ;
    2. Tu qualifies enfin cette expression entière en lui donnant son type propre, pour qu'elle puisse finalement être évaluée et ce, soit avec un nom de type terminal en toutes lettres, à gauche, soit en reprenant au point numéro 2 !

    Et comme le point numéro 2 est prioritaire par rapport au n° 3 et au n°4, tu peux utiliser des parenthèses dans la construction de ton expression pour forcer la priorité.

    Ainsi, une fonction admettant un int en entrée et te renvoyant un pointeur de fonction acceptant deux float et renvoyant un double se construirait ainsi :

    — « fnct » le nom de mon instance ;
    — « fnct(int) » suivie des parenthèses avec des types à l'intérieur : fonction ;
    — « * fnct(int) » précédée d'une étoile : l'expression entière est de type pointeur. Note que la priorité de 2. sur 3. fait que c'est ma « fonction qui est de pointeur » et non mon « pointeur qui pointe une fonction » ;
    — « (* fnct(int)) » ici, je suis obligé d'ajouter des parenthèses, sinon ce que je rajouterais à droite serait prioritaire sur mon pointeur. Mon expression est donc une fonction de type pointeur sur quelque chose. Mais quoi ?
    — « (* fnct(int))(float,float) » … sur une fonction, impliquée par mes parenthèses. Cette fonction attend donc deux _float ;
    — « double (* fnct(int))(float,float) » cette fonction est une expression mathématique qui peut être évaluée. Comme elle renvoie un double, je peux placer mon terminal « double » à gauche. Mais si elle renvoyait quelque chose de plus évolué, je pourrais très bien repartir pour un tour.

    À noter ainsi que je pourrais très bien faire une fonction qui renvoie non pas un pointeur de fonction mais… une autre fonction ! Syntaxiquement, ce serait possible. Exemple : une fonction « f » qui admettrait un int et renverrait une fonction de type « int g (void) » s'écrirait :

    int f(int)(void);

    En soi, ce serait un bon moyen d'implémenter les lambdas-fonctions. Bon, en fait, cela ne pourrait pas être écrit directement de cette façon car cela impliquerait que l'on puisse instancier plusieurs fois la même fonction. Mais le C++11 a quand même introduit une syntaxe pour le faire…

    L'opérateur de transtypage, maintenant, admet tout simplement un type, sans identifiant, entre une paire de parenthèses. Il faut donc simplement résoudre ce qui se trouve à l'intérieur sans se soucier de ce à quoi on l'applique, aller au bout de la procédure, et seulement ensuite examiner ce qui suit.

    à quoi ressemble un tableau de pointeur sur fonctions qui retournent un int en mémoire ?

    1. tableau
    2. tableau[]
    3. (* tableau)
    4. (* tableau)()
    5. int (* tableau)()

    est-ce que les argument des fonctions de ce tableau changent sa représentation ?

    Ça ne change pas la manière de les construire. Par contre, quand tu définis ce type, tu déclares dans la foulée les fonctions qu'il pointe. Il est donc nécessaire d'établir proprement leur signature, pour que le programme qui déréférence le pointeur puisse utiliser les fonctions qui sont pointées.

    En outre, il y a une subtilité qui dit qu'en C ISO, fnct() et fnct(void) sont identiques mais qu'en K&R, le premier sert simplement à déclarer l'existence de la fonction sans la décrire plus. Je ne sais pas si cela s'applique sur les définitions de type.

    J'imagine que par ailleurs c'est très dépendant de l’architecture.

    En principe, non. Un code C canonique propre est censé être parfaitement portable.