{"id":5283,"date":"2017-07-07T19:56:47","date_gmt":"2017-07-07T19:56:47","guid":{"rendered":"https:\/\/www.modernescpp.com\/index.php\/c-core-guidelines-interfaces\/"},"modified":"2023-06-26T12:10:30","modified_gmt":"2023-06-26T12:10:30","slug":"c-core-guidelines-interfaces","status":"publish","type":"post","link":"https:\/\/www.modernescpp.com\/index.php\/c-core-guidelines-interfaces\/","title":{"rendered":"C++ Core Guidelines: Interfaces I"},"content":{"rendered":"<p>Interfaces are a contract between a service provider and a service consumer. The C++ Core Guidelines has 20 rules to make them suitable because &#8220;interfaces is probably the most important single aspect of code organization&#8221;.<\/p>\n<p><!--more--><\/p>\n<p>&nbsp;<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-5282\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2017\/07\/Lego_dimensions.svg.png\" alt=\"Lego dimensions.svg\" width=\"600\" height=\"300\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2017\/07\/Lego_dimensions.svg.png 800w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2017\/07\/Lego_dimensions.svg-300x150.png 300w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2017\/07\/Lego_dimensions.svg-768x384.png 768w\" sizes=\"auto, (max-width: 600px) 100vw, 600px\" \/><\/p>\n<p>Before I dive into the rules, here is an overview of the 20 rules.<\/p>\n<ul>\n<li><a href=\"http:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#Ri-explicit\">I.1: Make interfaces explicit<\/a><\/li>\n<li><a href=\"http:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#Ri-global\">I.2: Avoid global variables<\/a><\/li>\n<li><a href=\"http:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#Ri-singleton\">I.3: Avoid singletons<\/a><\/li>\n<li><a href=\"http:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#Ri-typed\">I.4: Make interfaces precisely and strongly typed<\/a><\/li>\n<li><a href=\"http:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#Ri-pre\">I.5: State preconditions (if any)<\/a><\/li>\n<li><a href=\"http:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#Ri-expects\">I.6: Prefer <code class=\"highlighter-rouge no-highlight\">Expects()<\/code> for expressing preconditions<\/a><\/li>\n<li><a href=\"http:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#Ri-post\">I.7: State postconditions<\/a><\/li>\n<li><a href=\"http:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#Ri-ensures\">I.8: Prefer <code class=\"highlighter-rouge no-highlight\">Ensures()<\/code> for expressing postconditions<\/a><\/li>\n<li><a href=\"http:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#Ri-concepts\">I.9: If an interface is a template, document its parameters using concepts<\/a><\/li>\n<li><a href=\"http:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#Ri-except\">I.10: Use exceptions to signal a failure to perform a required task<\/a><\/li>\n<li><a href=\"http:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#Ri-raw\">I.11: Never transfer ownership by a raw pointer (<code class=\"highlighter-rouge no-highlight\">T*<\/code>)<\/a><\/li>\n<li><a href=\"http:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#Ri-nullptr\">I.12: Declare a pointer that must not be null as <code class=\"highlighter-rouge no-highlight\">not_null<\/code><\/a><\/li>\n<li><a href=\"http:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#Ri-array\">I.13: Do not pass an array as a single pointer<\/a><\/li>\n<li><a href=\"http:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#Ri-global-init\">I.22: Avoid complex initialization of global objects<\/a><\/li>\n<li><a href=\"http:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#Ri-nargs\">I.23: Keep the number of function arguments low<\/a><\/li>\n<li><a href=\"http:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#Ri-unrelated\">I.24: Avoid adjacent unrelated parameters of the same type<\/a><\/li>\n<li><a href=\"http:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#Ri-abstract\">I.25: Prefer abstract classes as interfaces to class hierarchies<\/a><\/li>\n<li><a href=\"http:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#Ri-abi\">I.26: If you want a cross-compiler ABI, use a C-style subset<\/a><\/li>\n<li><a href=\"http:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#Ri-pimpl\">I.27: For stable library ABI, consider the Pimpl idiom<\/a><\/li>\n<li><a href=\"http:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#Ri-encapsulate\">I.30: Encapsulate rule violations<\/a><\/li>\n<\/ul>\n<p>I will make my discussion of the rules not so elaborate because there are too many rules. My idea is to write in this post about the first ten rules and the next post about the remaining 10. So, let&#8217;s start.<\/p>\n<h4><strong>I.1: Make interfaces explicit<\/strong><\/h4>\n<p>This rule is about correctness and means: assumptions should be stated in an interface. Otherwise, they are easily overlooked and hard to test.<\/p>\n<div style=\"background: #f0f3f3; overflow: auto; width: auto; gray;border-width: .1em .1em .1em .8em;\">\n<pre style=\"margin: 0; line-height: 125%;\"><span style=\"color: #007788; font-weight: bold;\">int<\/span> <span style=\"color: #cc00ff;\">round<\/span>(<span style=\"color: #007788; font-weight: bold;\">double<\/span> d)\r\n{\r\n    <span style=\"color: #006699; font-weight: bold;\">return<\/span> (round_up) <span style=\"color: #555555;\">?<\/span> ceil(d) <span style=\"color: #555555;\">:<\/span> d;    <span style=\"color: #0099ff; font-style: italic;\">\/\/ don't: \"invisible\" dependency<\/span>\r\n}\r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<p>For example, the function <span style=\"font-family: courier new,courier;\">round<\/span> does not express that its result depends on the invisible dependency <span style=\"font-family: courier new,courier;\">round_up.<\/span><\/p>\n<h4><strong>I.2: Avoid global variables<\/strong><\/h4>\n<p>This rule is obvious, but the emphasis lies on mutable global variables. Global constants are fine because they cannot introduce a dependency into the function and cannot be subject to race conditions.<\/p>\n<h4><strong>I.3: Avoid singletons<\/strong><\/h4>\n<p>Singletons are global objects under the hood. Therefore, you should avoid them.<\/p>\n<\/p>\n<h4><strong>I.4: Make interfaces precisely and strongly typed<\/strong><\/h4>\n<p>The reason for this rule makes it clear: &#8220;Types are the simplest and best documentation, have a well-defined meaning, and are guaranteed to be checked at compile time.&#8221;<\/p>\n<p>Have a look at an example:<\/p>\n<div style=\"background: #f0f3f3; overflow: auto; width: auto; gray;border-width: .1em .1em .1em .8em;\">\n<pre style=\"margin: 0; line-height: 125%;\"><span style=\"color: #007788; font-weight: bold;\">void<\/span> <span style=\"color: #cc00ff;\">draw_rect<\/span>(<span style=\"color: #007788; font-weight: bold;\">int<\/span>, <span style=\"color: #007788; font-weight: bold;\">int<\/span>, <span style=\"color: #007788; font-weight: bold;\">int<\/span>, <span style=\"color: #007788; font-weight: bold;\">int<\/span>);   <span style=\"color: #0099ff; font-style: italic;\">\/\/ great opportunities for mistakes<\/span>\r\ndraw_rect(p.x, p.y, <span style=\"color: #ff6600;\">10<\/span>, <span style=\"color: #ff6600;\">20<\/span>);          <span style=\"color: #0099ff; font-style: italic;\">\/\/ what does 10, 20 mean?<\/span>\r\n\r\n<span style=\"color: #007788; font-weight: bold;\">void<\/span> <span style=\"color: #cc00ff;\">draw_rectangle<\/span>(Point top_left, Point bottom_right);\r\n<span style=\"color: #007788; font-weight: bold;\">void<\/span> <span style=\"color: #cc00ff;\">draw_rectangle<\/span>(Point top_left, Size height_width);\r\n\r\ndraw_rectangle(p, Point{<span style=\"color: #ff6600;\">10<\/span>, <span style=\"color: #ff6600;\">20<\/span>});  <span style=\"color: #0099ff; font-style: italic;\">\/\/ two corners<\/span>\r\ndraw_rectangle(p, Size{<span style=\"color: #ff6600;\">10<\/span>, <span style=\"color: #ff6600;\">20<\/span>});   <span style=\"color: #0099ff; font-style: italic;\">\/\/ one corner and a (height, width) pair<\/span>\r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<p>How easy is it to use the function <span style=\"font-family: courier new,courier;\">draw_rect<\/span> incorrectly? Compare this to the function <span style=\"font-family: courier new,courier;\">draw_rectangle.<\/span> The compiler guarantees that the argument is either a <span style=\"font-family: courier new,courier;\">Point<\/span> or a <span style=\"font-family: courier new,courier;\">Size<\/span> object.<\/p>\n<p>You should, therefore, look in your process of code improvement for functions with many built-in type arguments and, even worse, for functions that accept <span style=\"font-family: courier new,courier;\">void*<\/span> as a parameter.<\/p>\n<h4><strong>I.5: State preconditions (if any)<\/strong><\/h4>\n<p>If possible, preconditions such that<span style=\"font-family: courier new,courier;\"> x<\/span> in double <span style=\"font-family: courier new,courier;\">sqrt(double x)<\/span> must be non-negative should be expressed as assertions.<\/p>\n<p><span style=\"font-family: courier new,courier;\">Expects()<\/span> from the <a href=\"https:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#S-gsl\">Guideline support library<\/a> (GSL) let you express your precondition directly.<\/p>\n<div style=\"background: #f0f3f3; overflow: auto; width: auto; gray;border-width: .1em .1em .1em .8em;\">\n<pre style=\"margin: 0; line-height: 125%;\"><span style=\"color: #007788; font-weight: bold;\">double<\/span> <span style=\"color: #cc00ff;\">sqrt<\/span>(<span style=\"color: #007788; font-weight: bold;\">double<\/span> x) { Expects(x <span style=\"color: #555555;\">&gt;=<\/span> <span style=\"color: #ff6600;\">0<\/span>); <span style=\"color: #0099ff; font-style: italic;\">\/* ... *\/<\/span> }\r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<p>Contracts, consisting of preconditions, postconditions, and assertions, may be part of the next C++20 standard. See the proposal <a href=\"http:\/\/www.open-std.org\/jtc1\/sc22\/wg21\/docs\/papers\/2016\/p0380r1.pdf\">p03801.pdf<\/a>.<\/p>\n<h4><strong>I.6: Prefer Expects() for expressing preconditions<\/strong><\/h4>\n<p>That is similar to the previous rule, but the emphasis is on a different aspect. You should use <span style=\"font-family: courier new,courier;\">Expects()<\/span> for expressing preconditions and not, for example, an if expression, a comment, or an <span style=\"font-family: courier new,courier;\">assert()<\/span> statement.&nbsp;<\/p>\n<div style=\"background: #f0f3f3; overflow: auto; width: auto; gray;border-width: .1em .1em .1em .8em;\">\n<pre style=\"margin: 0; line-height: 125%;\"><span style=\"color: #007788; font-weight: bold;\">int<\/span> <span style=\"color: #cc00ff;\">area<\/span>(<span style=\"color: #007788; font-weight: bold;\">int<\/span> height, <span style=\"color: #007788; font-weight: bold;\">int<\/span> width)\r\n{\r\n    Expects(height <span style=\"color: #555555;\">&gt;<\/span> <span style=\"color: #ff6600;\">0<\/span> <span style=\"color: #555555;\">&amp;&amp;<\/span> width <span style=\"color: #555555;\">&gt;<\/span> <span style=\"color: #ff6600;\">0<\/span>);            <span style=\"color: #0099ff; font-style: italic;\">\/\/ good<\/span>\r\n    <span style=\"color: #006699; font-weight: bold;\">if<\/span> (height <span style=\"color: #555555;\">&lt;=<\/span> <span style=\"color: #ff6600;\">0<\/span> <span style=\"color: #555555;\">||<\/span> width <span style=\"color: #555555;\">&lt;=<\/span> <span style=\"color: #ff6600;\">0<\/span>) my_error();   <span style=\"color: #0099ff; font-style: italic;\">\/\/ obscure<\/span>\r\n    <span style=\"color: #0099ff; font-style: italic;\">\/\/ ...<\/span>\r\n}\r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<p>The expression<span style=\"font-family: courier new,courier;\"> Expects()<\/span> is easier to spot and may be checkable by the upcoming C++20 standard.<\/p>\n<h4><strong>I.7: State postconditions, I.8: Prefer Ensures() for expressing postconditions<\/strong><\/h4>\n<p>Following the arguments of a function, you have to think about its results. Therefore, the postcondition rules are pretty similar to previous precondition rules.<\/p>\n<h4><strong>I.9: If an interface is a template, document its parameters using concepts<\/strong><\/h4>\n<p>We will get with high probability with C++20 concepts. Concepts are predicates on template parameters that can be evaluated at compile time. A concept may limit the set of arguments accepted as template parameters. I already wrote four posts about <a href=\"https:\/\/www.modernescpp.com\/index.php\/tag\/concepts\">concepts<\/a>, because there is much more to concepts.<\/p>\n<p>The rule of the C++ Core Guidelines is quite easy. You should apply them.<\/p>\n<div style=\"background: #f0f3f3; overflow: auto; width: auto; gray;border-width: .1em .1em .1em .8em;\">\n<pre style=\"margin: 0; line-height: 125%;\"><span style=\"color: #006699; font-weight: bold;\">template<\/span><span style=\"color: #555555;\">&lt;<\/span><span style=\"color: #006699; font-weight: bold;\">typename<\/span> Iter, <span style=\"color: #006699; font-weight: bold;\">typename<\/span> Val<span style=\"color: #555555;\">&gt;<\/span>\r\nrequires InputIterator<span style=\"color: #555555;\">&lt;<\/span>Iter<span style=\"color: #555555;\">&gt;<\/span> <span style=\"color: #555555;\">&amp;&amp;<\/span> EqualityComparable<span style=\"color: #555555;\">&lt;<\/span>ValueType<span style=\"color: #555555;\">&lt;<\/span>Iter<span style=\"color: #555555;\">&gt;&gt;<\/span>, Val<span style=\"color: #555555;\">&gt;<\/span>\r\nIter find(Iter first, Iter last, Val v)\r\n{\r\n    <span style=\"color: #0099ff; font-style: italic;\">\/\/ ...<\/span>\r\n}\r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<p>The generic <span style=\"font-family: courier new,courier;\">find<\/span> algorithm requires that the template parameter <span style=\"font-family: courier new,courier;\">Iter<\/span> is an <span style=\"font-family: courier new,courier;\">InputIterator<\/span> and the underlying value of the template parameter <span style=\"font-family: courier new,courier;\">Iter<\/span> is <span style=\"font-family: courier new,courier;\">EqualityComparable<\/span>. If you invoke the <span style=\"font-family: courier new,courier;\">find<\/span> algorithm with a template argument that does not satisfy this requirement, you will get <strong>readable and easily understand<\/strong>&nbsp;the error message.<\/p>\n<h4><strong>I. 10: Use exceptions to signal a failure to perform a required task<\/strong><\/h4>\n<p>Here is why: &#8220;It should not be possible to ignore an error because that could leave the system or a computation in an undefined (or unexpected) state.&#8221;<\/p>\n<p>The rule provides a bad and a good example.<\/p>\n<div style=\"background: #f0f3f3; overflow: auto; width: auto; gray;border-width: .1em .1em .1em .8em;\">\n<pre style=\"margin: 0; line-height: 125%;\"><span style=\"color: #007788; font-weight: bold;\">int<\/span> <span style=\"color: #cc00ff;\">printf<\/span>(<span style=\"color: #006699; font-weight: bold;\">const<\/span> <span style=\"color: #007788; font-weight: bold;\">char<\/span><span style=\"color: #555555;\">*<\/span> ...);    <span style=\"color: #0099ff; font-style: italic;\">\/\/ bad: return negative number if output fails<\/span>\r\n\r\n<span style=\"color: #006699; font-weight: bold;\">template<\/span> <span style=\"color: #555555;\">&lt;<\/span><span style=\"color: #006699; font-weight: bold;\">class<\/span> <span style=\"color: #00aa88; font-weight: bold;\">F<\/span>, <span style=\"color: #006699; font-weight: bold;\">class<\/span> ...<span style=\"color: #00aa88; font-weight: bold;\">Args<\/span><span style=\"color: #555555;\">&gt;<\/span>\r\n<span style=\"color: #0099ff; font-style: italic;\">\/\/ good: throw system_error if unable to start the new thread<\/span>\r\n<span style=\"color: #006699; font-weight: bold;\">explicit<\/span> <span style=\"color: #006699; font-weight: bold;\">thread<\/span>(F<span style=\"color: #555555;\">&amp;&amp;<\/span> f, Args<span style=\"color: #555555;\">&amp;&amp;<\/span>... args);\r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<p>In the wrong case, you can ignore the exception, and your program has undefined behavior.<\/p>\n<p>You should return a pair of values if you didn&#8217;t use exceptions. Thanks to C++17 feature <a href=\"https:\/\/www.modernescpp.com\/index.php\/cpp17-core#h2-1-4-structured-binding-declarations\">structured binding<\/a>. You can do it quite elegantly.<\/p>\n<div style=\"background: #f0f3f3; overflow: auto; width: auto; gray;border-width: .1em .1em .1em .8em;\">\n<pre style=\"margin: 0; line-height: 125%;\"><span style=\"color: #006699; font-weight: bold;\">auto<\/span> [val, error_code] <span style=\"color: #555555;\">=<\/span> do_something();\r\n<span style=\"color: #006699; font-weight: bold;\">if<\/span> (error_code <span style=\"color: #555555;\">==<\/span> <span style=\"color: #ff6600;\">0<\/span>) {\r\n    <span style=\"color: #0099ff; font-style: italic;\">\/\/ ... handle the error or exit ...<\/span>\r\n}\r\n<span style=\"color: #0099ff; font-style: italic;\">\/\/ ... use val ...<\/span>\r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<h2>What&#8217;s next?<\/h2>\n<p>That is relatively easy to guess. In the <a href=\"https:\/\/www.modernescpp.com\/index.php\/c-core-guidelines-interfaces-ii\">next post<\/a>, I will write about the remaining rules to pointers, initialization of globals objects, function parameters, abstract classes, and ABI (application binary interface). There is a lot to know about good interface design.<\/p>\n<p>&nbsp;<\/p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Interfaces are a contract between a service provider and a service consumer. The C++ Core Guidelines has 20 rules to make them suitable because &#8220;interfaces is probably the most important single aspect of code organization&#8221;.<\/p>\n","protected":false},"author":21,"featured_media":5282,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[372],"tags":[477],"class_list":["post-5283","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-modern-c","tag-interfaces"],"_links":{"self":[{"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/5283","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/users\/21"}],"replies":[{"embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/comments?post=5283"}],"version-history":[{"count":1,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/5283\/revisions"}],"predecessor-version":[{"id":6806,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/5283\/revisions\/6806"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/media\/5282"}],"wp:attachment":[{"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/media?parent=5283"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/categories?post=5283"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/tags?post=5283"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}