Pour commencer tu n'as pas déclaré les prototypes de tes fonctions.
Tu n'es pas obligé de déclarer les prototypes. La norme autorise à ne pas le faire car une définition fait aussi office de déclaration.
Comment passer mes arguments à ma fonction? J'ai le choix entre: par valeur immédiate, par référence, par pointeur sans transfert de propriété, par pointeur avec transfert de propriété, par recopie (si mon objet définit un constructeur de recopie, et que celui-ci n'est pas cassé… ah mais au fait, c'est une copie superficielle, etc.) Et encore j'évite les hypothèses de type pointeur sur void avec information adjascente pour récupérer le type (c'est parfois une option sérieuse).
Non. Tu fais ce que tu veux en C++. Tu n'es même pas obligé de passer par le système orienté objet si tu n'aimes pas. Tu peux parfaitement faire du « C en C++ » avec juste l'avantage d'avoir un typage plus fort et oui, des références à la place des pointeurs quand ça a du sens.
Comment récupérer la valeur de ma fonction? Dans un argument que j'aurais moi-même passé en argument (par référence ou par pointeur?) ou bien dans une valeur de retour, ou bien je renvoie une référence ou un pointeur sur un espace de stockage privé?
Alors qu'en Bash, c'est tellement mieux : tu es obligé de déclarer une variable extérieure à ta fonction, qui vit dans un espace de nommage « global » et donc risque d'entrer en conflit avec d'autres variables (bref, c'est de ta faute si deux fonctions utilisent la/les même(s) nom(s) de variable(s) de retour).
Ensuite, tu utilises tout un vocabulaire compliqué (« espace de stockage privé » ? Vraiment ?). Il y a deux solutions globalement : soit tu renvoies une valeur avec ta fonction, soit tu écris dans une variable passée par référence (que ce soit une référence de type « pointeur » ou « référence C++ », ça reste du passage par référence). Ensuite, n'importe quel codeur C (même pas C++) sait que dès que le type devient un peu complexe, il est préférable (le plus souvent, il y a toujours des exceptions bien entendu) de passer un paramètre par référence (donc par pointeur en C, pointeur ou de préférence référence en C++). Bref, tu as en gros trois choix pour le retour :
typef(paramètres...);// par valeur, pour les toutes petites structures ou les types primitifsvoidf(paramètres...,type&retour);// pour tout le reste en grosvoidf(paramètres...,type*retour);// à utiliser en dernier recours, si on a besoin de manipuler le pointeur lui-même
Tout ce qui est qualification de type const, volatile, etc., rentre dans la notion de « type » dans ce contexte.
Je suis le même raisonnement général pour le passage de paramètres pour une fonction en C ou C++.
Comment signaler les erreurs?
Tu fais comme en C : tu utilises un entier/un enum pour le retour de ta fonction. Tu n'es pas obligé de passer par les exceptions. Tu n'es jamais obligé d'utiliser l'intégralité d'un langage, et c'est encore plus vrai en C++ où Stroustrup, Meyers, Sutter & co ne cessent de répéter qu'en C++ on ne paie que pour ce qu'on utilise. Rien ne t'oblige à faire de la méta-programmation à base de templates ou même de faire des fonctions templates si tu n'en as pas besoin. Rien ne t'oblige à faire du « C avec classes » si tu ne le veux pas. Et si tu le veux, rien ne t'empêche de jeter l'encapsulation par la fenêtre si tu veux juste un POD : déclare simplement des structures comme en C (avec l'avantage de pouvoir quand même définir des fonctions membres si tu veux faire un peu d'objet).
Évidemment, C++ est bien plus complexe que Bash, je ne le nie pas. Mais quand on me dit qu'en Bash il est bien plus simple de déclarer des fonctions qu'en C++, je suis très moyennement d'accord. Je me dis même qu'il suffirait de se donner une règle très simple pour « émuler » en partie la façon dont les fonctions Bash fonctionnent : toujours passer ses paramètres par référence constantes (types primitifs inclus), et si la fonction renvoie quelque chose, toujours fournir une/des variables passées elles aussi par référence.
Tu m'aurais dit « en Python/en Ruby, il est bien plus facile de déclarer des fonctions qu'en C++ », j'aurais déjà été plus d'accord. Ce qui me gêne dans les fonctions Bash, c'est l'absence de portée lexicale pour les valeurs de retour.
[^] # Re: Tableau
Posté par lasher . En réponse au journal Tu souhaites apprendre à programmer en shell. Évalué à 2.
Tu n'es pas obligé de déclarer les prototypes. La norme autorise à ne pas le faire car une définition fait aussi office de déclaration.
Non. Tu fais ce que tu veux en C++. Tu n'es même pas obligé de passer par le système orienté objet si tu n'aimes pas. Tu peux parfaitement faire du « C en C++ » avec juste l'avantage d'avoir un typage plus fort et oui, des références à la place des pointeurs quand ça a du sens.
Alors qu'en Bash, c'est tellement mieux : tu es obligé de déclarer une variable extérieure à ta fonction, qui vit dans un espace de nommage « global » et donc risque d'entrer en conflit avec d'autres variables (bref, c'est de ta faute si deux fonctions utilisent la/les même(s) nom(s) de variable(s) de retour).
Ensuite, tu utilises tout un vocabulaire compliqué (« espace de stockage privé » ? Vraiment ?). Il y a deux solutions globalement : soit tu renvoies une valeur avec ta fonction, soit tu écris dans une variable passée par référence (que ce soit une référence de type « pointeur » ou « référence C++ », ça reste du passage par référence). Ensuite, n'importe quel codeur C (même pas C++) sait que dès que le type devient un peu complexe, il est préférable (le plus souvent, il y a toujours des exceptions bien entendu) de passer un paramètre par référence (donc par pointeur en C, pointeur ou de préférence référence en C++). Bref, tu as en gros trois choix pour le retour :
Tout ce qui est qualification de type
const,volatile, etc., rentre dans la notion de « type » dans ce contexte.Je suis le même raisonnement général pour le passage de paramètres pour une fonction en C ou C++.
Tu fais comme en C : tu utilises un entier/un enum pour le retour de ta fonction. Tu n'es pas obligé de passer par les exceptions. Tu n'es jamais obligé d'utiliser l'intégralité d'un langage, et c'est encore plus vrai en C++ où Stroustrup, Meyers, Sutter & co ne cessent de répéter qu'en C++ on ne paie que pour ce qu'on utilise. Rien ne t'oblige à faire de la méta-programmation à base de templates ou même de faire des fonctions templates si tu n'en as pas besoin. Rien ne t'oblige à faire du « C avec classes » si tu ne le veux pas. Et si tu le veux, rien ne t'empêche de jeter l'encapsulation par la fenêtre si tu veux juste un POD : déclare simplement des structures comme en C (avec l'avantage de pouvoir quand même définir des fonctions membres si tu veux faire un peu d'objet).
Évidemment, C++ est bien plus complexe que Bash, je ne le nie pas. Mais quand on me dit qu'en Bash il est bien plus simple de déclarer des fonctions qu'en C++, je suis très moyennement d'accord. Je me dis même qu'il suffirait de se donner une règle très simple pour « émuler » en partie la façon dont les fonctions Bash fonctionnent : toujours passer ses paramètres par référence constantes (types primitifs inclus), et si la fonction renvoie quelque chose, toujours fournir une/des variables passées elles aussi par référence.
Tu m'aurais dit « en Python/en Ruby, il est bien plus facile de déclarer des fonctions qu'en C++ », j'aurais déjà été plus d'accord. Ce qui me gêne dans les fonctions Bash, c'est l'absence de portée lexicale pour les valeurs de retour.