À propos de ce qui est commun à
C et C++
Bien que les langages C et C++
soient plus distincts que les gens ne le croient, il reste que ce sont tout
de même des langages qui partagent un historique et qui ont quelques
points en commun, sur le plan syntaxique comme sur le plan conceptuel.
Contrairement à ce que plusieurs pensent, C
n'est pas un sous-ensemble de C++, et il
existe des programmes C qui ne sont pas acceptés
par un compilateur C++, le tout en pleine
conformité avec les standards. En retour, les intersections entre les
deux langages sont telles que plusieurs bibliothèques C
sont utilisables directement en C++, et que
des mécanismes sont en place pour faciliter les interactions entre
programmes rédigés dans ces deux langages.
Dans un souci de réduire la redondance, voici quelques liens touchant
ces deux langages à la fois (bien que souvent plus orientés
autour de C++ que de C).
Je les ai logés dans cette section plutôt que dans
celle portant sur C++ par choix
esthétique, sans plus.
Généralités
C et C++
interprété : http://root.cern.ch/drupal/content/cint
Foire aux questions sur C et C++ : http://www.comeaucomputing.com/techtalk/
Excellente référence pour C et C++ :
http://en.cppreference.com/w/Main_Page
Truc pour bien lire les déclarations :
Trucs particuliers à
Microsoft
Windows :
Outils :
Relations entre C et C++
Structures de contrôle
Quelques liens portant sur les structures de contrôle communes entre autres à
ces deux langages.
Par « alternatives », nous entendons en gros les
if et les else.
Alternatives
- Textes de Jonathan Boccarra en 2017 sur la
clarification de la présentation du code comprenant des alternatives :
Par « répétitives », nous entendons en gros les
while, les do...while et les
for.
Répétitives
Par « sélectives », nous entendons en gros les
switch.
Sélectives
- Une étude du code généré pour des sélectives
(article du Code Project) : http://www.codeproject.com/KB/cpp/switch.aspx
- Divers trucs amusants à connaître à propos des sélectives de C
et de C++,
article du Code Project
par Zuoliu Ding en 2015 :
http://www.codeproject.com/Articles/100473/Something-You-May-Not-Know-About-the-Switch-Statem
- Un commentaire de James Hague en 2013 à
l'effet que la sélective de C est en fait le plus
haut niveau d'abstraction offert par ce langage :
http://prog21.dadgum.com/166.html
- Examiner le code machine généré par une sélective, texte de
2013 : http://741mhz.com/switch/
- Décomposer une sélective pour mieux en comprendre le fonctionnement,
texte de 2015 :
http://www.rapitasystems.com/blog/breaking-switch-statement
- Une sélective, en C
ou en C++,
n'est au fond qu'un goto déguisé, dont il est possible de tirer profit pour
certaines manoeuvres... discutables :
../../Sources/facto-duff.html
- Réflexion sur les sélectives, proposée en 2016 :
https://eev.ee/blog/2016/09/18/the-curious-case-of-the-switch-statement/
- En 2015,
Linus
Torvalds prend position sur les sélectives appliquées à un booléen... et
il est en faveur :
https://lkml.org/lkml/2015/5/27/941
- En 2012, Zuolio Ding examine le code généré
par MSVC pour certaines sélectives :
https://www.codeproject.com/Articles/100473/Something-You-May-Not-Know-About-the-Switch-Statem
(aujourd'hui, on utiliserait sans doute
https://godbolt.org/ pour ce type d'étude)
- Texte de 2017 par
Jonathan
Boccara,
proposant des techniques pour aplatir des sélectives imbriquées :
http://www.fluentcpp.com/2017/06/27/how-to-collapse-nested-switch-statements/
- En 2018, Andrey Karpov liste quelques bogues
résultant de break oubliés dans une sélective :
https://www.viva64.com/en/b/0554/
Indirections
Les modalités d'indirection possibles en C
se limitent aux pointeurs, incluant pointeurs sur des pointeurs (sur des
pointeurs sur...) et pointeurs de fonctions. Celles de C++
incluent aussi les références et les
pointeurs
intelligents.
Pointeurs
- Pour un survol :
../AuSecours/Bref-pointeurs.html
- http://c-faq.com/ptrs/index.html
- http://c-faq.com/null/ (spécifiquement
consacré aux pointeurs nuls)
- Les pointeurs et les tableaux sont-ils équivalents? Non, comme le
rappelle Eli Bendersky en 2009 :
http://eli.thegreenplace.net/2009/10/21/are-pointers-and-arrays-equivalent-in-c
- http://susam.in/blog/clumsy-pointers/
- La nuance entre char[] et
char* : http://techblog.rosedu.org/arrays-vs-pointers.html
- Comprendre les déclarations de pointeurs, un texte de
2012 : http://hamberg.no/erlend/2012/02/21/cc-pointer-declaration-syntax-it-makes-sense/
- Introduction en cinq minutes aux pointeurs, par Dennis Kubes en
2012 :
http://denniskubes.com/2012/08/16/the-5-minute-guide-to-c-pointers/
- Introduction aux adresses, par Dennis Kubes en
2012 :
http://denniskubes.com/2012/08/17/basics-of-memory-addresses-in-c/
- Pointeurs de pointeurs, texte de 2013 :
http://wordaligned.org/articles/two-star-programming
- Le modèle abstrait d'une machine C et les adresses, en particulier
0 pour la gestion du pointeur nul et ~0
(0xffffffff sur une machine
32 bits), pour qu'il soit toujours possible d'aller à l'adresse juste
après la fin d'un tableau. Texte de
Raymond Chen en 2013 :
http://blogs.msdn.com/b/oldnewthing/archive/2013/03/28/10405881.aspx
- Arithmétique de pointeurs et
Undefined Behavior, texte de
Tudor Bosman en 2013 :
http://cppwisdom.quora.com/Pointer-arithmetic-in-C
- Différences subtiles entre les pointeurs avec C89 et C99, par Jon
Jarboe en 2013 :
https://communities.coverity.com/blogs/development-testing-blog/2013/09/11/array-parameters-conversion-and-lifetime-in-c
- Explication de ce que sont les pointeurs, par
Eric Lippert
en 2014 :
http://ericlippert.com/2014/05/12/what-are-the-fundamental-rules-of-pointers/
- Arithmétique de pointeurs, qu'on aime parfois mais qui a mauvaise
presse, par Matt Weisfeld en 2014 :
http://www.informit.com/articles/article.aspx?p=2246428
- Passer des pointeurs bruts en paramètre à une fonction, un texte
d'Arne Mertz en 2015 :
http://arne-mertz.de/2015/02/plain-pointers-as-function-parameters/
- En 2015, Sahil Bora explique les
pointeurs :
http://cppbetterexplained.com/understanding-and-breaking-down-pointers/
- Texte de 2016 par Krister Walfridsson qui trace une
distinction entre les pointeurs de C
et leur contrepartie matérielle :
http://kristerw.blogspot.ca/2016/03/c-pointers-are-not-hardware-pointers.html
- Conversions entre pointeurs avec C,
par Krister Walfridsson en 2016 :
http://kristerw.blogspot.ca/2016/03/pointer-casts-in-c.html
- En 2017, Jefferson Amstutz se dit d'avis que
les pointeurs bruts sont dangereux :
https://jeffamstutz.io/2017/03/31/plain-pointers-considered-harmful/
Pointeurs de fonctions
Lors d'une conversation sur Slack, en 2017, quelqu'un a fait remarquer que,
du fait que le nom d'une fonction est en fait son adresse, étant donné deux
fonctions de même signature comme sinus() et cosinus()
ci-dessous, l'appel suivant est
légal :
#include <cmath>
#include <iostream>
#include <locale>
using namespace std;
//
// définir des fonctions sinus et cosinus, car std::sin et std::cos ont toutes deux plusieurs signatures
//
double sinus(double x) {
return sin(x);
}
double cosinus(double x) {
return cos(x);
}
enum class choix { Sinus, Cosinus };
class erreur_lecture {};
choix choisir_fonction() {
const auto loc = locale{""};
cout << "[s]inus ou [c]osinus? ";
char c;
while (cin >> c && (c = tolower(c,loc), c != 's' && c != 'c')) {
cout << "[s]inus ou [c]osinus? ";
}
return c == 's'? choix::Sinus : c == 'c'? choix::Cosinus : throw erreur_lecture{};
}
int main() try {
using namespace std;
if (double x; cin >> x) { // C++17
cout << (choisir_fonction() == choix::Sinus? sinus : cosinus)(x) << endl; // <-- ICI
}
} catch (erreur_lecture&) {
cerr << "Erreur de lecture" << endl;
}
Avant de critiquer C ou C++, sachez que ce type de manoeuvre est idiomatique de langages tels que
Python, ce qui a d'ailleurs fait surgir la discussion sur C++
ce jour-là.
- Déréférencer un pointeur de fonction retourne ce pointeur, ce qui signifie qu'il est possible d'écrire du code... déstablisant, disons, avec cette syntaxe (tiré d'une conférence de James McNellis) :
https://pbs.twimg.com/media/CxoRxwmXcAAz5zT.jpg
Entiers
Les types entiers et leur saine manipulation, bien qu'au coeur de la
programmation, sont des objets de programmation périlleux en C
et en C++
dû aux règles de débordement, aux cas limites et aux risques de
comportement indéfini.
Tailles et distances
En C
comme en C++,
certains types jouent un rôle particulier dans la définition des tailles et des
distances : le type std::size_t est un type entier
non-signé qui sert à représenter les tailles des objets (c'est le type du nombre
d'éléments des tableaux, et c'est le type retourné par l'opérateur
sizeof), alors que le type std::ptrdiff_t est
un type entier signé qui sert à représenter les distances (c'est le type de la
différence entre deux pointeurs).
- Description de ces deux types, et de leur saine manipulation, en
particulier dans un contexte 64 bits, par Andrey
Karpov en 2009 :
http://www.viva64.com/en/a/0050/
Considérations techniques générales