-
Notifications
You must be signed in to change notification settings - Fork 0
/
Convenzioni_del_Linguaggio.tex
1951 lines (1284 loc) · 87.1 KB
/
Convenzioni_del_Linguaggio.tex
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
% --------------------- CONVENZIONI|LINEE GUIDA DEL LINGUAGGIO -----------------------
\chapter{Linee guida del Linguaggio} %TODO: oppure chiamarlo CppCoreGuidelines
% -------------------------- SECTION: INTRODUZIONE -----------------------------------
\section{Introduzione}
\textsf{\small In questo capitolo tratterò delle \textbf{CppCoreGuidelines} che sono delle linee guida del linguaggio, create dall'inventore del C++ \emph{Bjarne Stroustrup} e da \emph{Herb Sutter}.} \break
\textsf{\small Il \textbf{CppCoreGuidelines} non è uno standard ISO ufficiale.} \\
\textsf{\small Tratterò qui alcune di queste linee guida, ma sarebbe molto difficile trattarle tutte, visto che queste sono veramente tante. (credo più di 500 se non molto di più)} \break
\textsf{\small È difficile per me, trattare queste linee guida nello stesso modo esaustivo e con la stessa profondità delle \textbf{CppCoreGuidelines}, a volte elencherò solo i punti principali di una linea guida, comunque se volete controllare una specifica linea guida che ho trattato potete trovarla qui: \href{https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines}{CppCoreGuidelines}.} \\
\textsf{\small Ovviamente, ce ne sono tante altre buone che però non riuscirò a trattare.} \\
%\break %TODO: questo break rompe tutto!
% -------------------------- SECTION: CONVENZIONI ------------------------------------
\newpage
\section{Convenzioni del linguaggio}
\textsf{\small \textbf{Definizione: } Le \textbf{convenzioni} sono delle linee guida di un linguaggio che raccomandano un certo stile di programmazione. Queste permettono un codice più chiaro, più leggibile e rende il codice di un software più semplice da mantenere.} \\
\textsf{\small Inoltre, sia il codice che i commenti dovrebbero essere in inglese a differenza di come ho fatto io in questa guida.} \\
\textsf{\small Tratterò in primis le linee guida sui nomi e sul layout, presenti nella sezione di supporto: \emph{NL | Naming and Layout rules} delle \textbf{CppCoreGuidelines}.} \break
% -------------------- NL | NAMING AND LAYOUT RULES ----------------------------------
\subsection{NL | Naming and Layout suggestions}
\subsubsection{NL.1: Non dire nei commenti quello che può essere semplicemente affermato nel codice}
\textsf{\small I compilatori non leggono i commenti. I commenti sono meno precisi del codice. I commenti non vengono sempre aggiornati in modo costante come il codice.} \\
\subsubsection{NL.2: Indica l'intento nei commenti}
\textsf{\small Il codice dice ciò che è stato fatto, non quello che dovrebbe essere fatto. Spesso l'intento può essere indicato più chiaramente e concisamente che l'implementazione. } \\
\textsf{\small \textbf{Se i commenti e il codice sono in disaccordo, entrambi sono probabilmente errati}.} \\
\subsubsection{NL.3: Mantieni i commenti nitidi}
\textsf{\small La verbosità rallenta la comprensione e rende il codice più difficile da leggere diffondendolo nei sorgenti.} \\
\textsf{\small \textbf{Nota}: Usa l'inglese. Anche se sei madre lingua in un'altra lingua, usa l'inglese in modo che tutti i programmatori possano capire.} \\
\subsubsection{NL.4: Mantieni un'indentazione costante}
\textsf{\small Per via della leggibilità. Per evitare "sciocchi errori".} \\
\textsf{\small \textbf{Nota}: Sempre indentare dopo gli \textbf{if}, \textbf{for}, \textbf{while} è una buona idea.} \\
\subsubsection{NL.5: Evita la codifica delle informazioni sui tipi dei nomi} %TODO: tradurre meglio.
\textsf{\small Se i nomi riflettono i tipi rispetto alle funzionalità, diventerà difficile cambiare i tipi usati per fornire quella funzionalità. Inoltre, se il tipo di una variabile viene cambiato, il codice che la usa dovrà essere anch'esso modificato. Minimizza le conversioni non intenzionali.} \break
\textsf{\small Il seguente è un esempio \textbf{\color{red} ERRATO}\normalcolor:} \\
% frame=single, framexleftmargin=5mm, frame=shadowbox, rulesepcolor=\color{red}
\begin{lstlisting}[frame=single, rulecolor=\color{red}]
void print_int(int i);
void print_double(double d);
void print_string(const char*);
print_int(3);
print_double(3.69);
print_string("abc");
\end{lstlisting}
\textsf{\small Il seguente è un esempio \textbf{\color{ForestGreen} CORRETTO}\normalcolor:} \\
\begin{lstlisting}[frame=single, rulecolor=\color{ForestGreen}]
void print(int i);
void print(double d);
void print(string_view);
print(3);
print(3.69);
print("abc");
\end{lstlisting}
\textsf{\small \textbf{Nota}: I nomi con i tipi codificati al loro interno sono verbosi e criptici.} \\
\begin{lstlisting}
printS // print a std::string
prints // print a C-style string
printi // print an int
\end{lstlisting}
\textsf{\small Le tecniche come la \emph{notazione Ungherese} sono state usate nei linguaggi \emph{untyped} (senza tipi), ma è generalmente non necessario e persino dannoso in un linguaggio fortemente staticamente-tipizzato come il C++, perché le notazioni non vengono aggiornate e interferiscono con il buon uso del linguaggio.} \\
\subsubsection{NL.7: Fai si che la lunghezza di un nome sia proporzionale alla lunghezza del suo scope (raggio)}
\textsf{\small Più grande è lo scope (raggio), più grande è la possibilità di confusione e di "scontri" tra nomi.} \\
\subsubsection{NL.8: Usa uno stile dei nomi in modo costante}
\textsf{\small La costanza nei nomi e nel loro stile aumenta la leggibilità.} \\
\textsf{\small \textbf{Nota}: Ci sono molti stili, non puoi seguirli tutti, scegline uno, ma lascia lo stile delle librerie importate con il loro stile originale.} \\
\textsf{\small \textbf{Esempio}: Lo \emph{Standard ISO}, usa le lettere minuscole e le cifre, separando le parole con gli underscores (trattini bassi):}
\begin{itemize}
\item \textsf{\small int}
\item \textsf{\small vector}
\item \textsf{\small my\_map}
\end{itemize}
\textsf{\small Evita i doppi trattini bassi: \_\_} \\
\textsf{\small \textbf{Esempio}: Lo \emph{Stroustrup}: ISO Standard, ma con le lettere maiuscole usate per i tipi e i concetti definiti dall'utente. }
\begin{itemize}
\item \textsf{\small int}
\item \textsf{\small vector}
\item \textsf{\small My\_map}
\end{itemize}
\textsf{\small \textbf{Esempio}:\emph{CamelCase}, capitalizza ogni parola in un identificatore multi-parola: }
\begin{itemize}
\item \textsf{\small int}
\item \textsf{\small vector}
\item \textsf{\small MyMap}
\item \textsf{\small myMap}
\end{itemize}
\textsf{\small Alcune convenzioni capitalizzano la prima lettera, altre no.} \\
\subsubsection{NL.9: Usa ALL\_CAPS (tutte maiuscole) solo per i nomi delle macro}
\textsf{\small Per evitare di confondere le macro con i nomi che obbediscono allo scope (raggio) e regole del tipo.} \\
\textsf{\small \textbf{Nota}: Questa regola si applica anche alle costanti non-macro.} \\
\textsf{\small Applicazioni per assicurarci che venga rispettata: }
\begin{itemize}
\item \textsf{\small Segnalare tutte le macro con le lettere minuscole.}
\item \textsf{\small Segnala tutte le macro che non sono nella forma ALL\_CAPS.}
\end{itemize}
\subsubsection{NL.10: Preferire nomi con lo stile\_underscore (con i trattini bassi)}
\textsf{\small L'utilizzo degli underscores (trattini bassi) per separare parti del nome è originale dello stile del C e del C++ nella \emph{Libreria Standard del C++}.} \\
\textsf{\small \textbf{Nota}: Questa regola è un default soltanto se si ha la possibilità di scelta. Spesso, non si ha la possibilità di scelta e si deve seguire uno stile stabilito per coerenza. Il bisogno di costanza sconfigge il gusto personale.} \\
\textsf{\small \textbf{Esempio} \emph{Stroustrup}: ISO Standard, ma con le lettere maiuscole per i propri tipi e per i concetti: }
\begin{itemize}
\item \textsf{\small int}
\item \textsf{\small vector}
\item \textsf{\small My\_Map}
\end{itemize}
\subsubsection{NL.11: Rendi i letterali leggibili}
\textsf{\small Per la leggibilità del codice.} \\
\textsf{\small \textbf{Esempio} Usa i separatori nelle cifre per evitare lunghe stringhe di cifre.}
\begin{lstlisting}
auto c = 299'792'458; // m/s2
auto q2 = 0b0000'1111'0000'0000;
auto ss_number = 123'456'7890;
\end{lstlisting}
\textsf{\small \textbf{Esempio} Usa suffissi letterali quando necessario per chiarificare.}
\begin{lstlisting}
auto hello = "Hello!"s; // a std::string
auto world = "world"; // a C-style string
auto interval = 100ms; // using <chrono>
\end{lstlisting}
\textsf{\small \textbf{Nota}: I letterali (literals) non dovrebbero essere sparsi per l'intero codice come "magic constants", ma è comunque una buona idea per renderli chiari quando sono definiti. È semplice fare un typo in una lunga stringa di interi.} \\
\textsf{\small Il seguente è un esempio \textbf{\color{red}ERRATO}\normalcolor:}
\begin{lstlisting}[frame=single, rulecolor=\color{red}]
#include < chrono >
int main(int argc, char * argv [ ])
{
// ...
}
\end{lstlisting}
\textsf{\small Il seguente è un esempio \textbf{\color{ForestGreen}CORRETTO}\normalcolor:}
\begin{lstlisting}[frame=single, rulecolor=\color{ForestGreen}]
#include <chrono>
int main(int argc, char* argv[])
{
// ...
}
\end{lstlisting}
\textsf{\small Applicazioni per assicurare il rispetto della regola: }
\begin{itemize}
\item \textsf{\small Segnalare le lunghe sequenze di cifre. Il problema è definire "lunghe"; forse 7.}
\end{itemize}
\subsubsection{NL.15: Usa gli spazi con moderazione}
\textsf{\small Troppi spazi rendono il testo largo e distraente.} \\
\textsf{\small \textbf{Nota}: Gli spazi bianchi ben piazzati sono un aiuto significativo per la leggibilità. Basta non esagerare.} \\
\subsubsection{NL.16: Usa una convenzionale ordine di dichiarazione della classe}
\textsf{\small Un ordine convenzionale di membri migliora la leggibilità.} \\
\textsf{\small Quando dichiari una classe usa il seguente ordine: } \\
\begin{itemize}
\item \textsf{\small tipi: classi, enums, aliases (using)}
\item \textsf{\small costruttori, assegnamenti, distruttore}
\item \textsf{\small funzioni}
\item \textsf{\small dati}
\end{itemize}
\textsf{\small Usa l'ordine: \textbf{public} prima di \textbf{protected} prima di \textbf{private}. } \\
\begin{lstlisting}
class X {
public:
// interface
protected:
// unchecked function for use by derived class implementations
private:
// implementation details
};
\end{lstlisting}
\textsf{\small \textbf{Esempio} A volte, l'ordine di default dei membri va in conflitto con l'intenzione di separare l'interfaccia pubblica dai dettagli implementativi. In questi casi, i tipi privati e le funzioni possono essere piazzati con i dati privati.} \\
\textsf{\small \textbf{Esempio ERRATO}: Evita di dichiarare molteplici blocchi di accesso dispersi tra blocchi di dichiarazioni con differenti accessi. Il seguente esempio è \textbf{\color{red}ERRATO}\normalcolor: } \\
\begin{lstlisting}[frame=single, rulecolor=\color{red}]
class X { // bad
public:
void f();
public:
int g();
// ...
};
\end{lstlisting}
\textsf{\small L'utilizzo di macro per dichiarare gruppi di membri spesso porta a violazioni nelle regole di ordinamento. Comunque, usare le macro oscura quello che è stato espresso. } \\
\textsf{\small Applicazioni per il rispetto della regola: }
\begin{itemize}
\item \textsf{\small Segnala le partenze dall'ordine suggerito.}
\end{itemize}
\subsubsection{NL.17: Usa il layout di K\&R }
\textsf{\small Questo è il layout originale del C e C++. Preserva bene lo spazio verticale. Distingue bene i diversi costrutti del linguaggi (come le funzioni e le classi).} \\
\textsf{\small Questo può essere consultato al seguente link: \href{https://www.stroustrup.com/Programming/PPP-style.pdf}{PPP Style Guide}}
\textsf{\small \textbf{Nota}: Nel contesto del C++, questo stile è spesso chiamato \textbf{Stroustrup}.} \\
\textsf{\small \textbf{Esempio}}
\begin{lstlisting}
struct Cable {
int x;
// ...
};
double foo(int x)
{
if (0 < x) {
// ...
}
switch (x) {
case 0:
// ...
break;
case amazing:
// ...
break;
default:
// ...
break;
}
if (0 < x)
++x;
if (x < 0)
something();
else
something_else();
return some_value;
}
\end{lstlisting}
\textsf{\small Da notare lo spazio tra \textbf{if} e \textbf{$($}} \\
\textsf{\small \textbf{Nota}: Usa linee separate per per ogni statement, le parentesi di un \textbf{if} e il corpo di un \textbf{for}.} \\
\textsf{\small \textbf{Nota}: La \{ per una \textbf{class} e per una \textbf{struct} non è su una linea separata, ma la \{ per una funzione sì.} \\
\textsf{\small \textbf{Nota}: Capitalizza il nome dei tipi definiti dall'utente per distinguerli dai tipi della libreria standard.} \\
\textsf{\small \textbf{Nota}: Non capitalizzare i nomi delle funzioni.} \\
\textsf{\small Per applicare questa regola, usa un IDE per la formattazione.} \\
\subsubsection{NL.18: Usa il layout dei dichiaratori del C}
\textsf{\small Lo stile di layout del C enfatizza l'uso nelle espressioni e nella grammatica, mentre lo stile del C++ enfatizza i tipi. Questo non vale per le references.} \\ %TODO: "Questo non vale per le references" forse da tradurre meglio.
\textsf{\small \textbf{Esempio}}
\begin{lstlisting}
T& operator[](size_t); // OK
T &operator[](size_t); // semplicemente strano
T & operator[](size_t); // indeciso
\end{lstlisting}
\subsubsection{NL.19: Evita nomi che possono essere facilmente fraintesi}
\textsf{\small Per la leggibilità. Può capitare di confondere parole simili o errate.} \\
\textsf{\small \textbf{Esempio}}
\begin{lstlisting}
int oO01lL = 6; // male
int splunk = 7;
int splonk = 8; // male: splunk e splonk possono essere facilmente confusi
\end{lstlisting}
\subsubsection{NL.20: Non piazzare due dichiarazioni sulla stessa riga}
\textsf{\small Per via della leggibilità. È davvero semplice lasciarsi sfuggire una dichiarazione quando ce ne sono più di una in una linea.} \\
\textsf{\small \textbf{Esempio}}
\begin{lstlisting}
int x = 8; std::string s = "hello"; // non lo fare
int x = 8; f(x); ++x; // non lo fare
\end{lstlisting}
\subsubsection{NL.21: Dichiara un nome (solo) per dichiarazione}
\textsf{\small Per la leggibilità. Per minimizzare la confusione con la sintassi.} \\ %sintassi del dichiarante/di dichiarazione.
\textsf{\small \textbf{Nota}: Per i dettagli, guardare \textbf{ES.10} a pag.\textbf{\pageref{ES_10}}.} \\
\subsubsection{NL.25: Non usare void come argomento}
\textsf{\small È verboso, prolisso ed è necessario solo per questioni riguardanti la compatibilità col C.} \\
\textsf{\small \textbf{Esempio}}
\begin{lstlisting}
void f(void); // male
void f(); // meglio
\end{lstlisting}
\textsf{\small \textbf{Nota}: Persino Dennis Ritchie (creatore del C) considerava void f(void) un abominio. Lo si poteva fare in C e se lo si fosse vietato avrebbe causato grossi problemi, ma non lo si può usare nel 21° secolo e in C++. } \\
\subsubsection{NL.26: Usa la convenzionale notazione const}
\textsf{\small La notazione convenzionale è più familiare alla maggior parte dei programmatori. È importante per la coerenza nei grandi progetti, community} \\
\textsf{\small \textbf{Esempio}}
\begin{lstlisting}
const int x = 7; // OK
int const y = 9; // male
const int *const p = nullptr; // OK, constant pointer to constant int
int const *const p = nullptr; // male, constant pointer to constant int
\end{lstlisting}
\textsf{\small \textbf{Nota}: Gli esempi marcati "male" potrebbero sembrare più logici, ma confondono anche più persone, specialmente i principianti.} \break
\textsf{\small Come sempre, ricorda che lo scopo di queste regole di layout è la coerenza, la costanza e che l'estetica varia immensamente.} \\
\newpage
\textsf{\small Potete trovare tutte le linee guida del linguaggio nelle \textbf{C++ Core Guidelines} : \href{https://github.com/isocpp/CppCoreGuidelines}{CppCoreGuidelines}} \\
\begin{figure}[H]
\centering
\includegraphics[width=1\textwidth, height=1\textheight, keepaspectratio]{./imgs/CppCoreGuidelines.png}
\caption{CppCoreGuidelines}
\label{fig:CppCoreGuidelines}
\end{figure}
\textsf{\small Comunque ne elencherò qualche d'una. } \\
\subsection{Organizzazione} %TODO: oppure Struttura (però con qunado la si guarda nella toc struttura potrebbe confondersi con le strutture)
\textsc{\footnotesize Release 0.8} \\
\textsf{Le linee guide sono così suddivise: } \\
\textsf{Sezioni Maggiori: } \\ % volutamente senza lo \small.
\begin{multicols}{2}
\begin{itemize}
\item[In.] \textsf{\small \textbf{Introduction} }
\item[P.] \textsf{\small \textbf{Philosophy} }
\item[I.] \textsf{\small \textbf{Interfaces} }
\item[F.] \textsf{\small \textbf{Functions} }
\item[C.] \textsf{\small \textbf{Classes and class hierarchies} }
\item[Enum.] \textsf{\small \textbf{Enumerations} }
\item[R.] \textsf{\small \textbf{Resource Management} }
\item[ES.] \textsf{\small \textbf{Expressions and Statements} }
\item[Per.] \textsf{\small \textbf{Performance} }
\item[CP.] \textsf{\small \textbf{Concurrency and Parallelism} }
\item[E.] \textsf{\small \textbf{Error handling} }
\item[Con.] \textsf{\small \textbf{Constants and immutability} }
\item[T.] \textsf{\small \textbf{Templates and generic programming} }
\item[CPL.] \textsf{\small \textbf{C-style programming} }
\item[SF.] \textsf{\small \textbf{Source Files} }
\item[SL.] \textsf{\small \textbf{The Standard Library} }
\end{itemize}
\end{multicols}
\subsection{Sezioni Maggiori}
%TODO: volendo aggiungere qualche "Nota" e qualche esempio pratico di codice per tutte le subsubsection.
\textsf{\small Come detto, riuscirò a trattare solo alcune delle linee guide. Son veramente troppe!} \break
% -------------------------------- In | Introduction ---------------------------------
\subsubsection{In | Introduction}
\textsf{\small Lo scopo delle \textbf{CppCoreGuidelines} è quello di aiutare i programmatori a scrivere codice più semplice, più efficiente, più mantenibile.} \\
\textsf{\small Cercare di applicare tutte queste regole non è semplice.} \\
\textsf{\small Ma cerca di considerare queste linee guida, questi ideali quando scrivi codice e cerca di approssimarli il più possibile.} \break
% --------------------------------- P | PHILOSOPHY -----------------------------------
\subsubsection{P | Philosophy}
\textsf{\small Questa è una sezione molto generale che riguarda la \textbf{Philosophy} (Filosofia) delle linee guida.} \\
\textsf{\small Queste sono delle regole non meccaniche, ma regole individuali che riflettono temi filosofici. Senza una base filosofica, i concetti concreti, specifici mancherebbero di razionalità.}
\paragraph{P.1: Esprimi le idee direttamente nel codice}
\textsf{\small La motivazione principale è che i compilatori non leggono i commenti (o i documenti di design correlati) ovviamente e nemmeno tanti programmatori. Ciò che è espresso nel codice ha delle semantiche e può essere controllato dai compilatori e altri strumenti.} \\
\textsf{\small Mi raccomando usare \textbf{const} ove necessario. Rende chiaro l'intento che quella variabile, oggetto non deve essere modificato. Se non lo si mette, è il programmatore a dover indovinare se questo serve o no.} \\
\paragraph{P.2: Scrivi in ISO Standard C++}
\label{P_2}
\textsf{\small Questo è un insieme di linee guida per scrivere in \emph{ISO Standard C++}.} \\
\textsf{\small \textbf{Nota}: Usarle non garantisce \emph{portabilità}.} \\
\paragraph{P.3: Esprimi l'intento}
\textsf{\small A meno che l'intento del codice è chiaro (con i nomi o i commenti), è impossibile dire se il codice fa quello che dovrebbe.} \\
\textsf{\small \textbf{Nota}: Di' quello che dovrebbe essere fatto, piuttosto che come dovrebbe essere fatto.} \\
\paragraph{P.4: Idealmente, un programma dovrebbe essere staticamente type safe}
\textsf{\small Idealmente, un programma dovrebbe essere completamente staticamente (a compile-time) type safe.} \\
\textsf{\small Purtroppo, questo non è possibile. Per via di: }
\begin{multicols}{2}
\begin{itemize}
\item \textsf{\small unions}
\item \textsf{\small casts}
\item \textsf{\small array decay}
\item \textsf{\small errori di range}
\item \textsf{\small narrowing conversions (conversioni strette, limitate)}
\end{itemize}
\end{multicols}
\textsf{\small Alcune alternative per queste aree problematiche, per esempio: } \\
\begin{multicols}{2}
\begin{itemize}
\item \textsf{\small unions | usa \textbf{variant} (C++17)}
\item \textsf{\small casts | minimizza il loro utilizzo; i templates possono essere d'aiuto per questo.}
\item \textsf{\small array decay | usa \textbf{span} (dal GLSL)}
\item \textsf{\small errori di range | usa \textbf{span}}
\item \textsf{\small narrowing conversions | minimizza il loro utilizzo e usa \textbf{narrow} e \textbf{narrow\_cast}.}
%\item \textsf{\small }
\end{itemize}
\end{multicols}
\paragraph{P.5: Preferire i controlli a compile-time rispetto che a run-time}
\textsf{\small La ragione è per via della chiarezza e delle performance. Non hai bisogno di scrivere \emph{error handlers} per errori a compile time.} \\
\textsf{\small \textbf{Formulazione Alternativa}: Non posticipare a run time quello che può essere ben fatto a compile time.} \\
\textsf{\small \textbf{Applicazioni}: }
\begin{itemize}
\item \textsf{\small Guarda agli argomenti dei puntatori.}
\item \textsf{\small Guarda ai controlli a run-time per le violazioni di range.}
\end{itemize}
\paragraph{P.6: Quello che non può essere controllato a compile time dovrebbe essere controllato a run time}
\textsf{\small Lasciare degli errori difficili da scovare in un programma è chiedere per crashes e pessimi risultati.} \\
\textsf{\small \textbf{Nota}: Idealmente, cerchiamo di prendere tutti gli errori (che non sono nella logica del programmatore) o a compile time o a run time.} \\
%TODO: Enforcement
\paragraph{P.7: Prendere gli errori a run-time in anticipo} %TODO: oppure ... a run-time prima o presto
\textsf{\small Evita crashes "misteriosi". Evita errori che porterebbero (possibilmente non identificati) a risultati errati.} \\
\textsf{\small \textbf{Applicazioni}: } \\
\begin{itemize}
\item \textsf{\small Controlla i puntatori e gli arrays. Controlla i range prima e non ripetutamente.}
\item \textsf{\small Controlla le conversioni: Elimina o segna le \emph{narrowing conversions} (conversioni strette).}
\item \textsf{\small Controlla i valori non controllati che arrivano dall'input.}
\item \textsf{\small Controlla i dati strutturati (oggetti di classi invarianti) che vengono convertiti in stringhe.}
%\item \textsf{\small }
%\item \textsf{\small }
\end{itemize}
\paragraph{P.8: Non \emph{leakere} nessuna risorsa}
\textsf{\small Anche solo una piccola crescita nelle necessità di risorse, a lungo andare, esauriscono le risorse disponibili. Molto importante per programmi di vecchia data nel tempo, ma è un comportamento responsabile di ogni sviluppatore.} \\
\textsf{\small \textbf{Applicazioni}: }
\begin{itemize}
\item \textsf{\small Guarda i puntatori: Classificali in non-proprietari (di default) e proprietari. Quando possibile, rimpiazza quelli proprietari con gli \emph{handles} della libreria standard.}
\item \textsf{\small Guarda per \textbf{new} e \textbf{delete}.}
\item \textsf{\small Guarda alle funzioni che allocano risorse e restituiscono raw pointers (come fopen, malloc e strdup).}
\end{itemize}
\paragraph{P.9: Non perdere nè tempo nè spazio}
\textsf{\small Tempo e spazio che spendi per ottenere il risultato non è sprecato.} \\
\textsf{``Un altro beneficio di impegnarsi per l'efficienza è che il processo ti forza a capire il problema in più profondità``.}
\textsf{\emph{Alex Stepanov}.} \\
\textsf{\small \textbf{Applicazioni}: }
\begin{itemize}
\item \textsf{\small Segnala il valore di ritorno inutilizzato da un operatore++ o operatore-- in una funzione definita dall'utente e non di default. Preferire l'utilizzo della forma prefissa. }
%\item \textsf{\small }
%\item \textsf{\small }
\end{itemize}
\paragraph{P.10: Preferire i dati immutabili a quelli mutabili}
\textsf{\small Perché è più semplice pensare in termini di costanti che di variabili. Qualcosa di immutabile non può cambiare inaspettatamente. A volte gli immutabili permettono una migliore ottimizzazione. Non si può avere \emph{data race} (race condition) su una costante.} \\
\paragraph{P.11: Incapsula i costruttori disordinati, al posto di diffonderli nel codice}
\textsf{\small Il codice disordinato, confusionario è più probabile che nasconda bugs ed è più difficile da scrivere. Una buona interfaccia è più semplice e sicura da usare. Codice disordinato e di basso livello genera più codice di questo tipo.} \\
\textsf{\small \textbf{Applicazioni}: }
\begin{itemize}
\item \textsf{\small Cerca del "codice disordinato" come una complessa manipolazione di un puntatore e dei casts fuori dalle implementazioni delle astrazioni.}
%\item \textsf{\small }
%\item \textsf{\small }
\end{itemize}
\paragraph{P.12: Usa gli strumenti di supporto come è appropriato}
\textsf{\small Ci sono molte cose cose sono fatte meglio "dalle macchine". I computers non si stancano e non si annoiano delle tasks ripetitive.} \\
\textsf{\small Per esempio: } \\
\begin{itemize}
\item \textsf{\small \textbf{Static analysis tools}} %TODO: aggiungere link
\item \textsf{\small \textbf{Concurrency tools}} %TODO: aggiungere link
\item \textsf{\small \textbf{Testing tools}} %TODO: aggiungere link
\end{itemize}
\textsf{\small \textbf{Nota}: Cerca di non diventare dipendente sui tools (strumenti) troppo elaborati o specializzati. Questi potrebbero rendere il tuo codice non portabile.} \\
\paragraph{P.13: Usa le librerie supportate in modo appropriato}
\textsf{\small Usare le librerie ben progettate, ben documentate, e ben supportate salva tempo e impegno; Una libreria largamente diffusa è più probabile che verrà aggiornata e portata a nuovi sistemi.} \\
\textsf{\small Le conoscenze di una libreria molto usata possono farti risparmiare tempo sui tuoi futuri progetti. Quindi, se una libreria adatta esiste per la tua applicazione/ per il tuo dominio applicativo, allora usala.} \\
\textsf{\small \textbf{Nota}: Di default usa: }
\begin{itemize}
\item \textsf{\small \textbf{ISO C++ Standard Library}} %TODO: aggiungere link
\item \textsf{\small \textbf{Guidelines Support Library}} %TODO: aggiungere link
\end{itemize}
\textsf{\small \textbf{Nota}: Se una libreria ben progettata, ben documentata e ben supportata non esiste per il dominio che ti serve, allora dovresti progettarne una e implementarla e poi usarla.} \\
% --------------------------------- I | INTERFACES -----------------------------------
\newpage
\subsubsection{I | Interfaces}
\textsf{\small Un'interfaccia è un contratto tra due parti di un programma. Di cui, uno di questi è il \emph{supplier} (fornitore) del servizio e l'altro è l'utente del servizio. Affermando con precisione qual è il servizio che si prevede di fornire è essenziale.} \\
\textsf{\small Avere delle buone interfacce è probabilmente il singolo aspetto più importante dell'intera organizzazione del codice.} \\
\paragraph{I.1: Fai delle interfacce esplicite}
\textsf{\small Correttezza. Le assunzioni non precisate in un'interfaccia vengono semplicemente trascurate, tralasciate e difficili da testare. } \\
\begin{comment}
\textsf{\small \textbf{Applicazioni}: }
\begin{itemize}
\item \textsf{\small }
\item \textsf{\small }
\item \textsf{\small }
\end{itemize}
\end{comment}
\paragraph{I.2: Evita variabili globali non costanti}
\textsf{\small Le variabili globali non costanti nascondono delle dipendenze e rendono le dipendenze soggette a cambiamenti imprevedibili.} \\
\begin{comment}
\textsf{\small \textbf{Applicazioni}: }
\begin{itemize}
\item \textsf{\small }
\item \textsf{\small }
\item \textsf{\small }
\end{itemize}
\end{comment}
\paragraph{I.3: Evita i singletons}
\textsf{\small I singleton sono praticamente dei complicati oggetti globali celati} \\ %TODO: tradurlo meglio.
\begin{comment}
\textsf{\small \textbf{Applicazioni}: }
\begin{itemize}
\item \textsf{\small }
\item \textsf{\small }
\item \textsf{\small }
\end{itemize}
\end{comment}
\paragraph{I.4: Rendi le interfacce precise e fortemente typed}
\textsf{\small I tipi sono la documentazione migliore e più semplice, migliorano la leggibilità per via del loro significato ben definito e vengono controllati al tempo di compilazione. Inoltre, a volte, il codice precisamente "tipato" è spesso meglio ottimizzato.} \\
\begin{comment}
\textsf{\small \textbf{Applicazioni}: }
\begin{itemize}
\item \textsf{\small }
\item \textsf{\small }
\item \textsf{\small }
\end{itemize}
\end{comment}
\paragraph{I.5: Precondizioni di stato (se ce ne sono)}
\textsf{\small Gli argomenti hanno significati che potrebbero limitare il loro proprio utilizzo nel chiamante.} \\
\begin{comment}
\textsf{\small \textbf{Applicazioni}: }
\begin{itemize}
\item \textsf{\small }
\item \textsf{\small }
\item \textsf{\small }
\end{itemize}
\end{comment}
\paragraph{I.6: Preferisci \textbf{Expects()} per esprimere le precondizioni}
\textsf{\small Per rendere chiaro che la condizione è una precondizione e per consentire l'uso dello strumento.} \\ %TODO: tradurlo meglio.
\begin{comment}
\textsf{\small \textbf{Applicazioni}: }
\begin{itemize}
\item \textsf{\small }
\item \textsf{\small }
\item \textsf{\small }
\end{itemize}
\end{comment}
\paragraph{I.7: Postcondizioni di stato }
\textsf{\small Per rilevare malintesi riguardo al risultato e possibilmente individuare implementazioni errate.} \\
\begin{comment}
\textsf{\small \textbf{Applicazioni}: }
\begin{itemize}
\item \textsf{\small }
\item \textsf{\small }
\item \textsf{\small }
\end{itemize}
\end{comment}
\paragraph{I.8: Preferire \textbf{Ensures()} per esprimere postcondizioni}
\textsf{\small Per rendere chiaro che la condizione è una postcondizione e per consentire l'uso dello strumento.} \\ %TODO: tradurlo meglio.
\begin{comment}
\textsf{\small \textbf{Applicazioni}: }
\begin{itemize}
\item \textsf{\small }
\item \textsf{\small }
\item \textsf{\small }
\end{itemize}
\end{comment}
\paragraph{I.9: Se un'interfaccia è un template, allora documenta i suoi parametri usando i concepts}
\textsf{\small Rendi l'interfaccia precisamente specificata e controllata a compile-time (non così distante) nel futuro.} \\
\begin{comment}
\textsf{\small \textbf{Applicazioni}: }
\begin{itemize}
\item \textsf{\small }
\item \textsf{\small }
\item \textsf{\small }
\end{itemize}
\end{comment}
\paragraph{I.10: Usa le eccezioni per segnalare un fallimento nel performare una attività necessaria}
\textsf{\small Non dovrebbe essere possibile ignorare un errore perché questo potrebbe lasciare il sistema o la computazione in uno stato indefinito. Questa è una delle principali fonti di errori.} \\
\begin{comment}
\textsf{\small \textbf{Applicazioni}: }
\begin{itemize}
\item \textsf{\small }
\item \textsf{\small }
\item \textsf{\small }
\end{itemize}
\end{comment}
\paragraph{I.11: Non trasferire mai l'ownership (la proprietà) di un raw pointer (T*) o di una referenza (T\&)}
\textsf{\small Se si è in dubbio se un chiamante o un chiamato possiedono un oggetto, allora questo potrebbe portare a dei leaks o a una prematura distruzione dell'oggetto.} \\
\begin{comment}
\textsf{\small \textbf{Applicazioni}: }
\begin{itemize}
\item \textsf{\small }
\item \textsf{\small }
\item \textsf{\small }
\end{itemize}
\end{comment}
\paragraph{I.12: Dichiara un puntatore che \emph{non} deve essere \emph{null} come \emph{not\_null}}
\textsf{\small Per evitare di dereferenzare gli errori a \textbf{nullptr}. Per migliorare le performance evitando degli inutili controlli sul \textbf{nullptr}.} \\
\begin{comment}
\textsf{\small \textbf{Applicazioni}: }
\begin{itemize}
\item \textsf{\small }
\item \textsf{\small }
\item \textsf{\small }
\end{itemize}
\end{comment}
\paragraph{I.13: Non passare un array come un singolo puntatore}
\textsf{\small Le interfacce stile puntatori sono prone agli errori. Inoltre, un raw pointer ad un array deve dipendere su qualche convenzione per permettere al chiamato di determinare il size. } \\
\begin{comment}
\textsf{\small \textbf{Applicazioni}: }
\begin{itemize}
\item \textsf{\small }
\item \textsf{\small }
\item \textsf{\small }
\end{itemize}
\end{comment}
\paragraph{I.23: Mantieni il numero di argomenti in una funzione basso}
\textsf{\small Avere molti argomenti apre le porte alla possibilità di confusione. Passare molti argomenti è spesso costoso rispetto ad altre alternative.} \\
\begin{comment}
\textsf{\small \textbf{Applicazioni}: }
\begin{itemize}
\item \textsf{\small }
\item \textsf{\small }
\item \textsf{\small }
\end{itemize}
\end{comment}
% --------------------------------- F | Functions ------------------------------------
\newpage
\subsubsection{F | Functions}
\paragraph{F.21: Per restituire molteplici "out" values, preferire il ritorno di una struttura o di una tupla}
\textsf{\small Un valore di ritorno è auto esplicativo, si auto documenta come un valore soltanto di output. Si possono ritornare molteplici valori attraverso le \textbf{tuple} (\textbf{incluso i pair}) con la convenienza dell'usare \textbf{tie}.} \\
\textsf{\small \textbf{Applicazioni}: }
\begin{itemize}
\item \textsf{\small Gli "output parameters" dovrebbero essere rimpiazzati dai valori di ritorno. Un "output parameter" è uno a cui la funzione scrive, invoca un membro non costante o passa un non costante. } %TODO: da riscrivere.
%\item \textsf{\small }
%\item \textsf{\small }
\end{itemize}
\paragraph{F.51: Se c'è possibilità di scelta, preferisci gli argomenti di default rispetto all'overloading}
\textsf{\small Gli argomenti di default forniscono interfacce alternative ad una singola implementazione. Non c'è alcuna garanzia che un insieme di funzioni "overloaddate" implementano tutte le stesse semantiche. } \\
\textsf{\small L'utilizzo degli argomenti di default può evitare la replicazione del codice.} \\
% ----------------------- C | Classes and class hierarchies --------------------------
\newpage
\subsubsection{C | Classes and class hierarchies}
\paragraph{C.45: Non definire un costruttore di default solo per inizializzare dei dati membri; usa gli inizializzatori della classe piuttosto}
\textsf{\small Usare gli inizializzatori della classe permette al compilatore di generare la funzione per te. Le funzioni generate dal compilatore potrebbero essere più efficienti.} \\
\textsf{\small \textbf{Applicazioni}: }
\begin{itemize}
\item \textsf{\small Un default constructor dovrebbe fare di più che semplicemente inizializzare le variabili membro con delle costanti.}
%\item \textsf{\small }
%\item \textsf{\small }
\end{itemize}
\paragraph{C.47: Definisci e inizializza le variabili membro nell'ordine della loro dichiarazione}
\textsf{\small Per minimizzare la confusione e gli errori. Nell'ordine dell'inizializzazione succede.} \\
\textsf{\small \textbf{Applicazioni}: }
\begin{itemize}
\item \textsf{\small La lista di inizializzazione dovrebbe menzionare i membri nello stesso ordine in cui sono stati dichiarati.}
%\item \textsf{\small }
%\item \textsf{\small }
\end{itemize}
\paragraph{C.48: Preferisci gli inizializzatori nella classe al posto degli inizializzatori ai membri nei costruttori per gli inizializzatori costanti} %TODO: da scrivere meglio.
\textsf{\small Rende esplicito che lo stesso valore è da usare in tutti i costruttori. Evita la ripetizione. Evita i problemi di manutenzione. Porta a codice più corto ed efficiente.} \\
\textsf{\small \textbf{Applicazioni}: }
\begin{itemize}
\item \textsf{\small Ogni costruttore dovrebbe inizializzare ogni variabile membro (o esplicitamente attraverso una chiamata a costruttore o attraverso un costruttore di default).}
\item \textsf{\small Gli argomenti di default in un costruttore suggeriscono che un inizializzatore potrebbe essere più appropriato.}
%\item \textsf{\small }
\end{itemize}
% -------------------------------- Enum | Enumerations -------------------------------
\subsubsection{Enum | Enumerations}
\paragraph{Enum.3: Preferire le classi enum al posto degli enum "scoperti"} %TODO: migliorare la traduzione.
\textsf{\small Per ridurre le sorprese: gli enum tradizionali si convertono a int troppo facilmente.} \\
\textsf{\small \textbf{Applicazioni}: }
\begin{itemize}
\item \textsf{\small Avvertire (Warn, porre un warning) su qualsiasi definizione di un enum che non è in una classe.}
%\item \textsf{\small }
%\item \textsf{\small }
\end{itemize}
% ----------------------------- R | Resource Management ------------------------------
\newpage
\subsubsection{R | Resource Management}
\paragraph{R.10: Evita la malloc() e la free()}
\textsf{\small Perché non supportano la costruzione e distruzione e non si mescolano bene con \textbf{new} e \textbf{delete}.} \\
\textsf{\small \textbf{Applicazione per rispettare la regola}: }
\begin{itemize}
\item \textsf{\small Segnala l'uso esplicito della \emph{malloc} e della \emph{free}.}
\end{itemize}
\paragraph{R.11: Evita di chiamare \textbf{new} e \textbf{delete} in modo esplicito}
\textsf{\small Il puntatore ritornato dalla \textbf{new} dovrebbe appartenere al gestore della risorsa (che può chiamare la \textbf{delete}). Se il puntatore ritornato dalla \textbf{new} viene assegnato ad un puntatore, l'oggetto può essere "\emph{leakato}".} \\
\textsf{\small \textbf{Applicazione per rispettare la regola}: }
\begin{itemize}
\item \textsf{\small Poni un warning sull'uso esplicito della \textbf{new} e della \textbf{delete}. Suggerisci l'uso di \textbf{make\_unique} piuttosto.}
\end{itemize}
% ------------------------ ES | Expressions and Statements ---------------------------
\newpage
\subsubsection{ES | Expressions and Statements}
\label{ES_10}
\paragraph{ES.10: Dichiara solo un nome per dichiarazione}
\textsf{\small Una singola dichiarazione per linee migliora la leggibilità ed evita errori correlati alla grammatica del C/C++. Lascia anche spazio per un più descrittivo commento a fine linea. } \\
\textsf{\small Il seguente è un esempio \textbf{\color{red}ERRATO}\normalcolor: }
\begin{lstlisting}[frame=single, rulecolor=\color{red}]
char *p, c, q[7], *pp[7], **qq[10]; // male!
\end{lstlisting}
\textsf{\small \textbf{Eccezione} structured binding (C++17) è specificamente progettato per introdurre diverse variabili: }
\begin{lstlisting}
auto [iter, inserted] = m.insert_or_assign(k, val);
if (inserted) { /* new entry was inserted */ }
\end{lstlisting}
\textsf{\small \textbf{Applicazioni per il rispetto della regola}: }
\begin{itemize}
\item \textsf{\small Contrassegna le variabili e le costanti con più dichiaratori (esempio: int* p, q;).}
\end{itemize}
\paragraph{ES.46: Evita le conversione aritmetiche che perdono dati (narrowing, truncating)}
\textsf{\small Una conversione stretta (narrowing) distrugge le informazioni, spesso in modo inaspettato.} \\
\textsf{\small \textbf{Applicazioni}: } \\
textsf{\small Un buon analizzatore riesce a rilevare tute le conversioni strette (narrowing), però segnalarle tutte potrebbe portare a dei falsi positivi. Consigli: }
\begin{itemize}
\item \textsf{\small Segnala tutte le conversioni da numeri con la virgola (floating-point) a numeri interi (forse solo \textbf{float} \textrightarrow \textbf{char} e \textbf{double} \textrightarrow \textbf{int}).}
\item \textsf{\small Segnala \textbf{long} \textrightarrow \textbf{char} (anche \textbf{int} \textrightarrow \textbf{char}).}
\item \textsf{\small Considera le conversioni strette per gli argomenti delle funzioni molto sospette.}
\end{itemize}
\paragraph{ES.50: Non togliere il const col cast}
\textsf{\small Rende il \textbf{const} una menzogna. Se la variabile è dichiarata \textbf{const}, modificarla risulterebbe in un \emph{undefined behaviour} (comportamento indefinito).} \\
\textsf{\small Il seguente è un esempio \textbf{\color{red}ERRATO}\normalcolor:}
\begin{lstlisting}[frame=single, rulecolor=\color{red}]
void f(const int& x)
{
const_cast<int&>(x) = 42; // MALE
}
static int i = 0;
static const int j = 0;
f(i); // effetto collaterale silenzioso
f(j); // undefined behavior
\end{lstlisting}