-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathclass.html
1900 lines (1858 loc) · 58 KB
/
class.html
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
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="generator" content="AsciiDoc 9.0.0rc2, html5 backend 4.5.0">
<title>C Language Style for Scalability</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="author" content="Pieter Hintjens">
<!-- AsciiDoc Bootstrap styles -->
<link rel="stylesheet" type="text/css" id="bootstrapTheme" href="css/asciidoc-bootstrap.min.css">
<!--[if (lt IE 9) & (!IEMobile)]>
<script src="js/html5shiv.min.js"></script>
<script src="js/respond.min.js"></script>
<![endif]-->
<!-- 42ITy stylesheet -->
<link rel="stylesheet" type="text/css" href="css/42ity.css">
<!-- favorite icon -->
<link rel="shortcut icon" href="images/icons//favicon.ico">
</head>
<body id="toc-top">
<div id="page">
<header role="banner" class="Fixed">
<nav class="navbar navbar-default navbar-fixed-top" role="navigation">
<div class="container">
<div class="navbar-header">
<a class="navbar-brand" href="./">42ITy</a>
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
</div> <!-- /.navbar-header -->
<div class="navbar-collapse collapse">
<!-- Fixed navbar -->
<ul class="nav navbar-nav">
<li><a href="index.html">Home</a></li>
</ul>
<ul class="nav navbar-nav">
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">Download<span class="caret"></span></a>
<ul class="dropdown-menu">
<li><a href="source.html">Source code</a></li>
<li><a href="binaries.html">Binaries</a></li>
</ul>
</li>
</ul>
<ul class="nav navbar-nav">
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">Documentation<span class="caret"></span></a>
<ul class="dropdown-menu">
<li><a href="hcl.html">Supported Hardware</a></li>
<li role="separator" class="divider"></li>
<li><a href="presentation.html">Overall presentation</a></li>
<li><a href="contributing.html">Contributor guide</a></li>
</ul>
</li>
</ul>
<ul class="nav navbar-nav">
<li><a href="about.html">About</a></li>
</ul>
<ul class="nav navbar-nav">
<li><a href="contact.html">Contact</a></li>
</ul>
</div> <!-- /.navbar-collapse -->
</div> <!-- /.container -->
</nav>
</header>
<div id="content" class="container">
<div class="row">
<div class="col-md-9" role="main">
<div class="section">
<h1 class="page-header" id="c_language_style_for_scalability">C Language Style for Scalability</h1>
<div class="paragraph"><p>The C Language Style for Scalability (CLASS) defines a consistent style
and organization for scalable C library and application code built on
modern C compilers and operating systems. CLASS aims to collect industry
best practice into one reusable standard.</p></div>
<div class="paragraph"><p>CLASS was created by Pieter Hintjens, originally for the ZeroMQ project,
and is available as a ZeroMQ RFC
(
<a href="https://rfc.zeromq.org/spec:21/CLASS/">CLASS (C Language Style for Scalability)</a> ).</p></div>
<div class="paragraph"><p>This version of CLASS amends the original linked above in a few points:</p></div>
<div class="ulist"><ul>
<li>
<p>
clarification of ZeroMQ vs. IETF "RFC"s;
</p>
</li>
<li>
<p>
added Unix shared libraries, pkg-config declarations, and service
management definitions for daemons to the list of things that a project
SHOULD deliver;
</p>
</li>
<li>
<p>
revised "verbatim" markup in-lined in the text, and fixed a few typos;
</p>
</li>
<li>
<p>
requirement by default of <code>asciidoc</code> compatible markup for text files
and source comments, unless a different markup is not easily avoidable
(this and other aspects of documentation style, format and tooling were
since relocated into a separate document:
<a href="doc-recommendation.html">Documentation Recommendation</a>);
</p>
</li>
<li>
<p>
added standard text-processing programs among "dependencies" for the
projects which aim to deliver rendered end-user documentation formats;
</p>
</li>
<li>
<p>
the template README file markup made compatible with <code>asciidoc</code>.
</p>
</li>
</ul></div>
<h2 id="license">License</h2>
<div class="paragraph"><p>Copyright (c) 2009-2013 iMatix Corporation</p></div>
<div class="paragraph"><p>This Specification is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as published
by the Free Software Foundation; either version 3 of the License, or (at
your option) any later version.</p></div>
<div class="paragraph"><p>This Specification is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
Public License for more details.</p></div>
<div class="paragraph"><p>You should have received a copy of the GNU General Public License along
with this program; if not, see <a href="http://www.gnu.org/licenses">http://www.gnu.org/licenses</a>.</p></div>
<h2 id="change-process">Change Process</h2>
<div class="paragraph"><p>This Specification is a free and open standard (see
"<a href="http://www.digistan.org/open-standard:definition">Definition of a Free
and Open Standard</a>") and is governed by the Digital Standards
Organization’s Consensus-Oriented Specification System (COSS) (see
"<a href="http://www.digistan.org/spec:1/COSS">Consensus Oriented Specification
System</a>").</p></div>
<h2 id="language">Language</h2>
<div class="paragraph"><p>The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT",
"SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this
document are to be interpreted as described in IETF RFC 2119 (see
"<a href="http://tools.ietf.org/html/rfc2119">Key words for use in RFCs to
Indicate Requirement Levels</a>").</p></div>
<h2 id="goals">Goals</h2>
<div class="paragraph"><p>CLASS aims to be a complete and reusable style and organization guide
for scalable C projects. CLASS collects best practice to solve a set of
specific and well-known quality problems with C projects. It evolved
from the style guide of the ZeroMQ <a href="https://github.com/zeromq/czmq">CZMQ
project</a>. CLASS is plug compatible with the "coding style guide"
requirements of the C4 process (see
"<a href="http://rfc.zeromq.org/spec:16">Collective Code Construction Contract</a>")
and its revisions.</p></div>
<div class="paragraph"><p>The specific goals for this Specification are to:</p></div>
<div class="ulist"><ul>
<li>
<p>
Give project maintainers and contributors a tool for measuring the
quality of patches to a project.
</p>
</li>
<li>
<p>
Give the code the appearance of a single perfect author writing at one
moment in time.
</p>
</li>
<li>
<p>
Reduce the number of lines of code and complexity of C projects.
</p>
</li>
<li>
<p>
Ensure total consistency of every line of code, across a large number
of projects.
</p>
</li>
<li>
<p>
Reduce the risk of writing C code by solving common C style problems
in a minimal fashion.
</p>
</li>
<li>
<p>
Provide a vehicle to collect best practice over time.
</p>
</li>
</ul></div>
<h3 id="quality-aspirations">Quality Aspirations</h3>
<div class="paragraph"><p>The goal of CLASS is to help programmers write high-quality C code in a
consistent fashion. We define "high quality" primarily thus:</p></div>
<div class="ulist"><ul>
<li>
<p>
The code is easy to read and understand even if you know little or
nothing about its specific context.
</p>
</li>
<li>
<p>
The code is easy to reuse and remix, in whole or in fragments.
</p>
</li>
<li>
<p>
The code is easy to write correctly, and errors are rapidly clear.
</p>
</li>
</ul></div>
<div class="paragraph"><p>Our main tool for achieving this is to identify and apply the best
patterns and styles. The reader can learn these once, and then see them
repeatedly across a wide body of code. Deviations from familiar patterns
can then be taken as a sign of low-quality code that is more likely to
contain errors and less remixable.</p></div>
<h3 id="common-problems">Common Problems</h3>
<div class="paragraph"><p>With this Specification we aim to address a specific set of problems
that hurt the quality, remixability, and economics of many C projects:</p></div>
<div class="ulist"><ul>
<li>
<p>
If there is no style guide for a project, the maintainers must either
rewrite contributions by hand (which costs extra work), or must abandon
any attempt to enforce a consistent "voice" across a project (which
hurts code quality and reusability). Thus maintainers need a written
style guide to which they can point contributors.
</p>
</li>
<li>
<p>
If there is no reusable style guide, each project founder will
improvise their own ad hoc style. This wastes previous experience, and
creates unnecessary work for project founders. It also means each
project will end up with a different style.
</p>
</li>
<li>
<p>
If a set of projects each have a different style, they cannot share
code easily, which damages the economics of remixing. The more projects
that use a single style, the lower the cost of code reuse. This is
especially important in open source but also applies to projects built
internally in an organization.
</p>
</li>
<li>
<p>
With no vehicle for collecting and sharing best practices in C
programming, most projects will have mediocre structuring and style,
leading to unnecessary complexity, excess lines of code, accumulation of
unused code, and other quality problems.
</p>
</li>
<li>
<p>
When project founders create a new project without help, they often
make mistakes such as forgetting to define a license for their code.
This can create legal problems.
</p>
</li>
</ul></div>
<div class="paragraph"><p>While these problems can affect all software projects, we solve them
specifically for C projects.</p></div>
<h2 id="general-style">General Style</h2>
<h3 id="definitions">Definitions</h3>
<div class="paragraph"><p>The overall unit of work is a <em>project</em> that builds as a library with a
set of executable test programs and supplemental command-line tools.</p></div>
<div class="paragraph"><p>The project is composed of <em>classes</em>, where each class covers one area
of work and is implemented as a source file with matching header file.</p></div>
<div class="paragraph"><p>Each class implements a series of <em>methods</em>, where each method performs
one task and is implemented as a C function.</p></div>
<h3 id="language-1">Language</h3>
<div class="paragraph"><p>The language for all names and comments SHALL be English.</p></div>
<h3 id="naming">Naming</h3>
<div class="paragraph"><p>Names SHOULD be chosen for ease of readability, and consistency. Unless
otherwise specified, the following style rules apply to all given names:</p></div>
<div class="ulist"><ul>
<li>
<p>
Names SHALL be short words that are simple, clear, and obvious to the
reader.
</p>
</li>
<li>
<p>
Names SHALL be used consistently for any given semantics.
</p>
</li>
<li>
<p>
Names SHOULD NOT be invented words or acronyms.
</p>
</li>
<li>
<p>
Names MAY be abbreviations if used widely.
</p>
</li>
<li>
<p>
Names SHALL NOT be reserved C or C++ keywords.
</p>
</li>
</ul></div>
<h2 id="project-style">Project Style</h2>
<h3 id="project-focus">Project Focus</h3>
<div class="paragraph"><p>The project SHALL focus on one identifiable problem space, which SHALL
be stated explicitly in the project <code>README</code>.</p></div>
<h3 id="project-name">Project Name</h3>
<div class="paragraph"><p>The project SHALL have these short names and abbreviations:</p></div>
<div class="ulist"><ul>
<li>
<p>
A <em>project short name</em> used in paths and URLs that identify the
project. This would be used for instance in the GitHub project name.
In this Specification we will use <code>myproject</code> as the example.
</p>
</li>
<li>
<p>
A <em>project prefix</em> used for project files, output libraries, and
method names. This would be used for instance in the library produced
for the project. The prefix MAY be an acronym. In this Specification we
will use <code>myp</code> as the example.
</p>
</li>
</ul></div>
<div class="paragraph"><p>These names SHALL be noted in the project <code>README</code>.</p></div>
<h3 id="general-layout">General Layout</h3>
<div class="paragraph"><p>The project SHALL contain at least these files and directories:</p></div>
<div class="ulist"><ul>
<li>
<p>
A <code>README</code> file that refers to this Specification and provides other
necessary information about the project.
</p>
</li>
<li>
<p>
A license file (e.g., <code>COPYING</code> or <code>LICENSE</code>) that specifies the terms
of distribution for the project.
</p>
</li>
<li>
<p>
An <code>include</code> directory for all header files.
</p>
</li>
<li>
<p>
A <code>src</code> directory for all library source files.
</p>
</li>
<li>
<p>
The <em>public header file</em> (<code>include/myproject.h</code>).
</p>
</li>
<li>
<p>
Scripts and makefiles to build and test the project on at least one
platform.
</p>
</li>
</ul></div>
<div class="paragraph"><p>The project MAY contain these files and directories which MUST have
these names if present at all:</p></div>
<div class="ulist"><ul>
<li>
<p>
An <code>AUTHORS</code> file listing all contributors to the project.
</p>
</li>
<li>
<p>
A <code>doc</code> directory containing documentation.
</p>
</li>
<li>
<p>
The <em>internal header file</em> (<code>src/myp_classes.h</code>).
</p>
</li>
</ul></div>
<div class="paragraph"><p>The project SHOULD install these files:</p></div>
<div class="ulist"><ul>
<li>
<p>
The project header files and all class header files that form part of
the public API.
</p>
</li>
<li>
<p>
The project library, named with the project prefix (<code>libmyp.a</code> and/or
<code>libmyp.so(.*)</code> on POSIX platforms and <code>libmyp.pc</code> declarations for the
<code>pkg-config</code>, and <code>myp.dll</code> on Windows).
</p>
</li>
<li>
<p>
Command-line tools, if present.
</p>
</li>
<li>
<p>
Distribution-dependent service files for programs intended to run as
daemons (e.g. classic init-scripts, systemd units, Solaris SMF manifests).
</p>
</li>
</ul></div>
<h3 id="dependencies">Dependencies</h3>
<div class="paragraph"><p>The project SHALL depend at least on CZMQ (<code>libczmq</code>), which imports
ZeroMQ (<code>libzmq</code>), to provide portable APIs around networking, threads,
file systems, and other aspects.</p></div>
<div class="paragraph"><p>The project SHALL depend at least on <code>asciidoc</code> to render end-user formats
of documentation. It MAY depend on use of <code>xmlto</code>, <code>docbook</code>, <code>fo</code>, <code>a2x</code>,
<code>ghostscript</code> and other common backends and tools for rendering of specific
final formats. The project SHALL NOT depend on tools not available freely
to anybody as required part of its documentation processing recipes (e.g.
as a component of the <code>make distcheck</code> recipe chain).</p></div>
<h3 id="project-header-files">Project Header Files</h3>
<div class="paragraph"><p>The project SHALL provide two services via header files:</p></div>
<ol>
<li>
A set of internal definitions to class source files, which a class
source file can access with a single <code>#include</code> statement.
</li>
<li>
A public API that calling applications can access with a single
<code>include</code> statement.
</li>
</ol>
<div class="paragraph"><p>These two services MAY be combined into one project header file
(<code>myproject.h</code>), or MAY be split into an public header file
(<code>include/myproject.h</code>) and an internal header file (<code>src/myp_classes.h</code>).
The project MAY further break down these header files if necessary.</p></div>
<div class="paragraph"><p>The public header file SHALL define a version number for the project as
follows:</p></div>
<div class="listingblock">
<div class="content monospaced">
<pre>// MYPROJECT version macros for compile-time API detection
#define MYPROJECT_VERSION_MAJOR 1
#define MYPROJECT_VERSION_MINOR 0
#define MYPROJECT_VERSION_PATCH 0
#define MYPROJECT_MAKE_VERSION(major, minor, patch) \
((major) * 10000 + (minor) * 100 + (patch))
#define MYPROJECT_VERSION \
MYPROJECT_MAKE_VERSION(MYPROJECT_VERSION_MAJOR, \
MYPROJECT_VERSION_MINOR, \
MYPROJECT_VERSION_PATCH)</pre>
</div></div>
<div class="paragraph"><p>The project header file SHALL assert the required version numbers for
any dependencies immediately after including their respective header
files, like this:</p></div>
<div class="listingblock">
<div class="content monospaced">
<pre>#include <czmq.h>
#if CZMQ_VERSION < 10203
1. error "myproject needs CZMQ/1.2.3 or later"
#endif</pre>
</div></div>
<div class="paragraph"><p>Definitions in the public header file are visible to calling
applications as well as class source code. The public header file SHALL
<code>#include</code> all class header files that form part of the public API for the
project.</p></div>
<div class="paragraph"><p>Definitions in the internal header file are visible only to class source
code. The internal header file, if present, SHALL include the public
header file, all class header files, and all system and library header
files needed by the project. The primary goal here is to keep delicate
system-dependent <code>#include</code> chains in a single place, and away from class
source code.</p></div>
<h3 id="template-readme-file">Template README File</h3>
<div class="admonition note">
<div class="icon">
<img src="images/icons//note.png" alt="Note">
</div>
<div class="content">A copy of the sample below is committed into the repository as
<code>README-CLASS-template.asciidoc</code>.</div>
</div>
<div class="listingblock">
<div class="content monospaced">
<pre>Project Title
=============
Maintainter Name <[email protected]>
== Project Title
<One-paragraph statement of the goals of the project, and the problems
it aims to solve>.
== References
* Contribution policy is defined by C4 (http://rfc.zeromq.org/spec:42).
* Project style guide is defined by CLASS (http://rfc.zeromq.org/spec:21).
** short name: <shortname>
** prefix: <prefix>
* Licensed under <license name>, see COPYING
* Language level: C99</pre>
</div></div>
<div class="admonition note">
<div class="icon">
<img src="images/icons//note.png" alt="Note">
</div>
<div class="content">Update links to C4 and CLASS version adhered to by the project.</div>
</div>
<h3 id="language-level">Language Level</h3>
<div class="paragraph"><p>The project SHOULD use the C99 language for best clarity, but MAY use
the C89 language for compatibility with older platforms. The language
level SHALL be noted in the project README and all source code SHALL
conform to it.</p></div>
<div class="admonition note">
<div class="icon">
<img src="images/icons//note.png" alt="Note">
</div>
<div class="content">Microsoft Visual C/C++ does <em>not</em> support C99 and projects must
build using C++ language extensions to get access to C99 syntax. Because
of this, projects SHOULD NOT use any C99 syntax that is not a strict
subset of C++.</div>
</div>
<h3 id="use-of-the-preprocessor">Use of the Preprocessor</h3>
<div class="paragraph"><p>Project source code SHOULD NOT include any header files except the
project header file. This ensures that all class source code compiles in
exactly the same environment.</p></div>
<div class="paragraph"><p>Project source code SHALL NOT define "magic numbers" (numeric
constants); these SHALL be defined in the external or internal header
file, as appropriate.</p></div>
<div class="paragraph"><p>Projects MAY use the preprocessor for these purposes:</p></div>
<div class="ulist"><ul>
<li>
<p>
To create backwards compatibility with older code.
</p>
</li>
<li>
<p>
To improve portability by e.g., mapping non-portable system calls into
more portable ones.
</p>
</li>
<li>
<p>
To create precise, small macros with high usability.
</p>
</li>
</ul></div>
<div class="paragraph"><p>Projects SHOULD NOT use the preprocessor for other work except when it
significantly reduces the complexity of code.</p></div>
<div class="paragraph"><p>Macro names SHALL be uppercase when they represent constants, and
lowercase when they act as functions.</p></div>
<h2 id="class-styles">Class Styles</h2>
<h3 id="file-organization">File Organization</h3>
<div class="paragraph"><p>Each class SHALL be written as two files:</p></div>
<div class="ulist"><ul>
<li>
<p>
A header file: <code>include/myp_myclass.h</code>
</p>
</li>
<li>
<p>
A source file: <code>src/myp_myclass.c</code>
</p>
</li>
</ul></div>
<div class="paragraph"><p>These two files SHALL be the original documentation for the class.
Specifically, the class header SHALL define the API for the class, and
the class source file SHALL define the implementation of each method.</p></div>
<div class="paragraph"><p>Class names SHALL follow the General Style for Naming. We will use
<code>myclass</code> in examples.</p></div>
<div class="paragraph"><p>Every source and header file SHALL start with an appropriate file header
that states at least:</p></div>
<div class="ulist"><ul>
<li>
<p>
The name of the class or file and its purpose
</p>
</li>
<li>
<p>
The copyright statement for the class
</p>
</li>
<li>
<p>
The name of the project and a URL if relevant
</p>
</li>
<li>
<p>
The summary license statement
</p>
</li>
</ul></div>
<div class="paragraph"><p>Here is a template file header for an MPLv2 open source project:</p></div>
<div class="listingblock">
<div class="content monospaced">
<pre>/* =========================================================================
<name> - <description>
Copyright (c) the Contributors as noted in the AUTHORS file.
This file is part of MYPROJ, see https://github.com/MYORG/MYPROJ.
This Source Code Form is subject to the terms of the Mozilla Public
License, v. 2.0. If a copy of the MPL was not distributed with this
file, You can obtain one at http://mozilla.org/MPL/2.0/.
=========================================================================
*/</pre>
</div></div>
<h3 id="class-types">Class Types</h3>
<div class="paragraph"><p>We define two types of class:</p></div>
<div class="ulist"><ul>
<li>
<p>
<em>Stateful classes</em>, where the class provides methods working on
<em>instances</em>, which are like "objects" in an object-oriented language.
</p>
</li>
<li>
<p>
<em>Stateless classes</em>, where the class provides methods that work purely
on data provided by the caller or system.
</p>
</li>
</ul></div>
<div class="paragraph"><p>A stateful class SHALL provide these methods:</p></div>
<div class="ulist"><ul>
<li>
<p>
A constructor method <code>myp_myclass_new ()</code>
</p>
</li>
<li>
<p>
A destructor method <code>myp_myclass_destroy ()</code>
</p>
</li>
<li>
<p>
A self-test method <code>myp_myclass_test ()</code>
</p>
</li>
</ul></div>
<div class="paragraph"><p>A stateful class MAY provide these methods, and SHALL use these names
when providing such functionality:</p></div>
<div class="ulist"><ul>
<li>
<p>
A duplicator method <code>myp_myclass_dup ()</code>
</p>
</li>
<li>
<p>
A set of list navigation methods <code>myp_myclass_first ()</code> and
<code>myp_myclass_next ()</code>.
</p>
</li>
<li>
<p>
Print methods <code>myp_myclass_print ()</code> and <code>myp_myclass_fprint ()</code>.
</p>
</li>
</ul></div>
<div class="paragraph"><p>A stateless class SHALL provide at least this method:</p></div>
<div class="ulist"><ul>
<li>
<p>
A self-test method <code>myp_myclass_test ()</code>.
</p>
</li>
</ul></div>
<h3 id="method-names">Method Names</h3>
<div class="paragraph"><p>Method names SHALL follow the General Style for Naming. Method names
SHOULD be verbs ("destroy", "insert", "lookup") or adjectives ("ready",
"empty", "new"). The method name SHOULD imply the method return type,
where verbs return a success/failure indicator, if anything, and
adjectives return a value or instance.</p></div>
<h3 id="class-header-file">Class Header File</h3>
<div class="paragraph"><p>The class header file SHALL have this layout:</p></div>
<div class="ulist"><ul>
<li>
<p>
The file header
</p>
</li>
<li>
<p>
An outer <code>#ifndef</code> that makes it safe to include the header file
multiple times
</p>
</li>
<li>
<p>
Calling conventions for C++
</p>
</li>
<li>
<p>
A forward reference to the class type, for stateful classes
</p>
</li>
<li>
<p>
Prototypes for the class methods
</p>
</li>
</ul></div>
<div class="paragraph"><p>Here is a template header file for stateful classes, not showing the
file header:</p></div>
<div class="listingblock">
<div class="content monospaced">
<pre>#ifndef __MYMOD_H_INCLUDED__
#define __MYMOD_H_INCLUDED__
#ifdef __cplusplus
extern "C" {
#endif
// Opaque class structure
typedef struct _myp_myclass_t myp_myclass_t;
// Create a new <class name> instance
CZMQ_EXPORT myp_myclass_t *
myp_myclass_new (void);
// Destroy a <class name> instance
CZMQ_EXPORT void
myp_myclass_destroy (myp_myclass_t **self_p);
// Self test of this class
void
myp_myclass_test (bool verbose);
#ifdef __cplusplus
}
#endif
#endif</pre>
</div></div>
<div class="paragraph"><p>Here is a similar template header file for stateless classes:</p></div>
<div class="listingblock">
<div class="content monospaced">
<pre>#ifndef __MYMOD_H_INCLUDED__
#define __MYMOD_H_INCLUDED__
#ifdef __cplusplus
extern "C" {
#endif
// Self test of this class
int
myp_myclass_test (bool verbose);
#ifdef __cplusplus
}
#endif
#endif</pre>
</div></div>
<div class="paragraph"><p>All public methods SHALL be declared with <code>CZMQ_EXPORT</code> in the class
header file so that these methods are properly exported on operating
systems that require it.</p></div>
<h3 id="class-source-file">Class Source File</h3>
<div class="paragraph"><p>The class source file SHALL define:</p></div>
<div class="ulist"><ul>
<li>
<p>
The class structure, for stateful classes. This structure SHALL be
<em>opaque</em> and known only to code in the class source file.
</p>
</li>
<li>
<p>
The class methods, in the same order as defined in the class header:
constructor, destructor, other methods, and finally self test.
</p>
</li>
<li>
<p>
Any static functions used in the class methods.
</p>
</li>
<li>
<p>
Any global or static variables needed.
</p>
</li>
</ul></div>
<h3 id="class-properties">Class Properties</h3>
<div class="paragraph"><p>For stateful classes, the class structure has one or more properties
defined as a private C structure in the class source file.</p></div>
<div class="paragraph"><p>This SHOULD be defined as follows:</p></div>
<div class="listingblock">
<div class="content monospaced">
<pre>// Structure of our class
struct _myclass_t {
<type> <name>; // <description>
};</pre>
</div></div>
<div class="paragraph"><p>Property names SHALL follow the General Style for Naming. Property names
SHOULD be nouns or adjectives (typically used for Boolean properties).
We will use <code>myprop</code> in examples.</p></div>
<h2 id="method-styles">Method Styles</h2>
<h3 id="general-rules">General Rules</h3>
<h4>Argument Names</h4>
<div class="paragraph"><p>Argument names SHALL be consistent with property names.</p></div>
<h4>Return Values</h4>
<div class="paragraph"><p>Success/failure SHALL be indicated by returning an <code>int</code>, with values
<code>0</code> or <code>-1</code> respectively.</p></div>
<div class="paragraph"><p>Strings SHALL be returned as <code>char *</code> when they are passed to the
caller, who must free them.</p></div>
<div class="paragraph"><p>Strings SHALL be returned as <code>const char *</code> when the caller may not
modify or free them.</p></div>
<div class="paragraph"><p>Compound return values, e.g. a size-specified buffer, SHOULD be returned
as fresh objects of a suitable class. The API SHOULD NOT return compound
values via multiple routes, e.g. data via an argument and size via the
return code.</p></div>
<h3 id="the-self-test-method">The Self Test Method</h3>
<div class="paragraph"><p>In stateless classes, the only standard method is <code>myp_myclass_test ()</code>,
which SHALL conduct a self test of the class, returning silently on
success, and asserting on failure.</p></div>
<div class="paragraph"><p>The self test method shall take this general form:</p></div>
<div class="listingblock">
<div class="content monospaced">
<pre>// --------------------------------------------------------------------------
// Runs selftest of class
void
myp_myclass_test (int verbose)
{
printf (" * myp_myclass: ");
// Conduct tests of every method
printf ("OK\n");
}</pre>
</div></div>
<div class="ulist"><ul>
<li>
<p>
The self test method SHALL be a primary source of example code for
users of the class.
</p>
</li>
<li>
<p>
The self test method SHOULD cover every other method in the class.
</p>
</li>
</ul></div>
<h3 id="stateful-classes">Stateful Classes</h3>
<h4>The Constructor Method</h4>
<div class="paragraph"><p>The constructor SHALL take this general form:</p></div>
<div class="listingblock">
<div class="content monospaced">
<pre>// Create a new myp_myclass instance
myp_myclass_t *
myp_myclass_new (<arguments>)
{
myp_myclass_t *self = (myp_myclass_t *) zmalloc (sizeof (myp_myclass_t));
assert (self);
self->someprop = someprop_new ();
assert (self->someprop);
return self;
}</pre>
</div></div>
<div class="ulist"><ul>
<li>
<p>
The constructor SHALL initialize all properties in new class
instances. Properties SHALL either get a suitable initial value, or be
set to zero. Very large properties MAY exceptionally be left
uninitialized for performance reasons; such behavior MUST be explicitly
noted in the constructor body.
</p>
</li>
<li>
<p>
Any properties that are dynamically allocated SHOULD be allocated in
the constructor but MAY be left as null.
</p>
</li>
<li>
<p>
The constructor MAY take one or more arguments, which SHALL correspond
to properties to be initialized.
</p>
</li>
<li>
<p>
The constructor SHALL return either a new instance reference, or null,
if construction failed.
</p>
</li>
</ul></div>
<h4>The Destructor Method</h4>
<div class="paragraph"><p>The destructor SHALL take this general form:</p></div>
<div class="listingblock">
<div class="content monospaced">
<pre>// Destroy a myp_myclass instance
void
myp_myclass_destroy (myp_myclass_t **self_p)
{
assert (self_p);
if (*self_p) {
myp_myclass_t *self = *self_p;
someprop_destroy (&self->someprop);
anotherprop_destroy (&self->anotherprop);
lastprop_destroy (&self->lastprop);
free (self);
*self_p = NULL;
}
}</pre>
</div></div>
<div class="ulist"><ul>
<li>
<p>
The destructor SHALL <code>null</code>-ify the provided instance reference.
</p>
</li>
<li>
<p>
The destructor SHALL be idempotent, i.e. it can be called safely on the
same instance reference more than once.
</p>
</li>
<li>
<p>
The destructor SHALL safely free properties and child class instances
that are not <code>null</code>.
</p>
</li>
</ul></div>
<h4>The Duplicator Method</h4>
<div class="paragraph"><p>The class MAY offer a duplicator method which creates a full copy of an
instance; if it offers such semantics, the method MUST be called
<code>myp_myclass_dup ()</code> and take this general form:</p></div>
<div class="listingblock">
<div class="content monospaced">
<pre>// Create a copy of a myp_myclass instance
myp_myclass_t *
myp_myclass_dup (myp_myclass_t *self)
{
if (self) {
assert (self);
myp_myclass_t *copy = myp_myclass_new (...);
if (copy) {
// Initialize copy
}
return copy;
}
else
return NULL;
}</pre>
</div></div>
<div class="ulist"><ul>
<li>
<p>
The duplicator SHALL return either a new instance reference, or <code>null</code>
if construction failed, in the same manner as the constructor.
</p>
</li>
<li>
<p>
The duplicator SHALL accept a <code>null</code> instance reference, and then return
<code>null</code>.
</p>
</li>
<li>
<p>
A duplicated instance SHALL be entirely independent of the original
instance (i.e. all properties SHALL also be duplicated).
</p>
</li>
</ul></div>
<h4>List Navigation Methods</h4>
<div class="paragraph"><p>A class MAY act as a list container for other items, which may be child
class instances, strings, memory blocks, or other structures.</p></div>
<div class="paragraph"><p>Such a container class SHALL keep the list cursor position in the
instance, and provide the following methods for navigating the list:</p></div>
<div class="listingblock">
<div class="content monospaced">