{"id":214,"date":"2017-07-09T11:14:31","date_gmt":"2017-07-09T11:14:31","guid":{"rendered":"http:\/\/cppdepend.com\/wordpress\/?p=214"},"modified":"2023-05-31T16:10:48","modified_gmt":"2023-05-31T16:10:48","slug":"exploring-sqlite-codebase-improve-cpp-skills","status":"publish","type":"post","link":"https:\/\/cppdepend.com\/blog\/exploring-sqlite-codebase-improve-cpp-skills\/","title":{"rendered":"Exploring SQLite Codebase: Improve C++ Skills"},"content":{"rendered":"<p><a href=\"http:\/\/article.gmane.org\/gmane.comp.db.sqlite.general\/102084\">16 years after its first checkin<\/a>, SQLite is the\u00a0<a href=\"https:\/\/www.sqlite.org\/mostdeployed.html\">most widely deployed<\/a>\u00a0database engine in the world. An\u00a0open source project such as this is a good candidate for\u00a0learning how to make your code easy to understand and to maintain.<\/p>\n<p>Let\u2019s discover some facts about the SQLite code base, beginning with the following code snippet:<!--more--><span id=\"more-2392\"><\/span><\/p>\n<p><a href=\"http:\/\/www.codergears.com\/Blog\/wp-content\/uploads\/sqlite1.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-2395\" src=\"http:\/\/www.codergears.com\/Blog\/wp-content\/uploads\/sqlite1.png\" alt=\"sqlite\" width=\"592\" height=\"398\" \/><\/a><\/p>\n<p>Here are some remarks concerning this function:<\/p>\n<ul>\n<li>The function\u00a0is declared as static.<\/li>\n<li>The function return an error code.<\/li>\n<li>The function has few parameters.<\/li>\n<li>The\u00a0function exit as early as possible.<\/li>\n<li>Assert technique is used to check some conditions.<\/li>\n<li>No global variable used.<\/li>\n<li>The \u00a0variable naming is easy to understand.<\/li>\n<li>The method is short.<\/li>\n<li>\u00a0No extra comments in the body.<\/li>\n<li>The function body is well indented.<\/li>\n<\/ul>\n<p>If we\u00a0navigate across the SQLite source code we can remark the coherence of the implementation. The same best practice rules are applied to each function.<\/p>\n<p>Here are some best practices to learn from\u00a0the SQLite codebase:<\/p>\n<p><strong>Use structs to store your data model<\/strong><\/p>\n<p>In C programming the functions use variables to achieve their treatments. Theses variables could be:<\/p>\n<ul>\n<li>Static variables.<\/li>\n<li>Global variables.<\/li>\n<li>Local variables<\/li>\n<li>Variables from structs.<\/li>\n<\/ul>\n<p>Each project has its data model which can\u00a0be used by many source files. Using global variables is a solution but not the good one; instead, using structs to group data is more recommended.<\/p>\n<p>Let\u2019s search using CQlinq and <a href=\"http:\/\/www.cppdepend.com\/\">CppDepend<\/a> for defined structs:<\/p>\n<p><a href=\"http:\/\/www.codergears.com\/Blog\/wp-content\/uploads\/sqlite22.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-1929\" src=\"http:\/\/www.codergears.com\/Blog\/wp-content\/uploads\/sqlite22.png\" alt=\"sqlite22\" width=\"399\" height=\"556\" \/><\/a><\/p>\n<p>Many structs are used to specify the data model.<\/p>\n<p><strong>Let function be short and sweet<\/strong><\/p>\n<p>Here\u2019s some advice about the length of functions from the\u00a0<a href=\"https:\/\/www.kernel.org\/doc\/Documentation\/CodingStyle\">linux coding style web page<\/a>:<\/p>\n<pre>Functions should be short and sweet, and do just one thing.  They should\r\nfit on one or two screenfuls of text (the ISO\/ANSI screen size is 80x24,\r\nas we all know), and do one thing and do that well.\r\n\r\nThe maximum length of a function is inversely proportional to the\r\ncomplexity and indentation level of that function.  So, if you have a\r\nconceptually simple function that is just one long (but simple)\r\ncase-statement, where you have to do lots of small things for a lot of\r\ndifferent cases, it's OK to have a longer function.<\/pre>\n<p>Let\u2019s search for functions where the number of lines of code is less\u00a0than 30<\/p>\n<p><a href=\"http:\/\/www.codergears.com\/Blog\/wp-content\/uploads\/sqlite5.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-1934\" src=\"http:\/\/www.codergears.com\/Blog\/wp-content\/uploads\/sqlite5.png\" alt=\"sqlite5\" width=\"400\" height=\"506\" \/><\/a><\/p>\n<p>More than 90% of functions\u00a0have less than 30 lines of code.<\/p>\n<p><strong>Encapsulation<\/strong><\/p>\n<p>Encapsulation \u00a0is the hiding of functions and data which are internal to an implementation. \u00a0In C, encapsulation is performed by using the static keyword . These entities are called file-scope functions and variables.<\/p>\n<p>Let\u2019s search for all static functions by executing the following CQLinq query<\/p>\n<p><a href=\"http:\/\/www.codergears.com\/Blog\/wp-content\/uploads\/sqlite2.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-2402\" src=\"http:\/\/www.codergears.com\/Blog\/wp-content\/uploads\/sqlite2.png\" alt=\"sqlite\" width=\"441\" height=\"546\" \/><\/a><\/p>\n<p>As we can observe many functions are declared as static.<\/p>\n<p><strong>Function Number of parameters<\/strong><\/p>\n<p>Functions\u00a0where NbParameters &gt; 8\u00a0might be painful to call \u00a0and might degrade performance. Another alternative is to provide \u00a0a structure dedicated to handle arguments passing.<\/p>\n<p><a href=\"http:\/\/www.codergears.com\/Blog\/wp-content\/uploads\/sqlite6.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-1935\" src=\"http:\/\/www.codergears.com\/Blog\/wp-content\/uploads\/sqlite6.png\" alt=\"sqlite6\" width=\"404\" height=\"519\" \/><\/a><\/p>\n<p>Only a few\u00a0methods have more than 8 parameters.<\/p>\n<p><strong>Number of\u00a0local variables<\/strong><\/p>\n<p>Methods where NbVariables is\u00a0higher than 8 are hard to understand and maintain. Methods where NbVariables is\u00a0higher than 15 are extremely complex and should be split into smaller methods (unless\u00a0they are automatically generated by a tool).<\/p>\n<p><a href=\"http:\/\/www.codergears.com\/Blog\/wp-content\/uploads\/sqlite7.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-1936\" src=\"http:\/\/www.codergears.com\/Blog\/wp-content\/uploads\/sqlite7.png\" alt=\"sqlite7\" width=\"402\" height=\"546\" \/><\/a><\/p>\n<p>Only a few\u00a0functions have\u00a0more than 15 local variables.<\/p>\n<p><strong>Avoid defining complex functions<\/strong><\/p>\n<p>Many metrics exist to detect complex functions, NBLinesOfCode, Number of parameters and number of local variables are the basic ones.<\/p>\n<p>There are other interesting metrics to detect complex functions:<\/p>\n<ul>\n<li>Cyclomatic complexity is a popular procedural software metric where the result is equal to the number of decisions that can be taken in a procedure.<\/li>\n<li>Nesting Depth\u00a0is a metric defined on methods that is relative to the maximum depth\u00a0of the more nested scope in a method body.<\/li>\n<li>Max Nested loop is\u00a0equal to the maximum level of loop nesting in a function.<\/li>\n<\/ul>\n<p>The max value tolerated for these metrics depends more on the team choices, as there are no standard values.<\/p>\n<p>Let\u2019s search for possible functions to be refactored:<\/p>\n<p><a href=\"http:\/\/www.codergears.com\/Blog\/wp-content\/uploads\/sqlite8.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-1937\" src=\"http:\/\/www.codergears.com\/Blog\/wp-content\/uploads\/sqlite8.png\" alt=\"sqlite8\" width=\"435\" height=\"512\" \/><\/a><\/p>\n<p>Only very few functions could be considered complex.<\/p>\n<p><strong>Be Const Correct<\/strong><\/p>\n<p>C provides the\u00a0<em>const<\/em>\u00a0key word to allow objects passing that cannot change to bypass parameters and indicates when a method doesn\u2019t modify its object. Using const in all the right places is called \u201cconst correctness.\u201d It\u2019s hard at first, but using const really tightens up your coding style.<\/p>\n<p>Let\u2019s search for functions having at least one const parameter:<\/p>\n<p><a href=\"http:\/\/www.codergears.com\/Blog\/wp-content\/uploads\/sqlite9.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-1938\" src=\"http:\/\/www.codergears.com\/Blog\/wp-content\/uploads\/sqlite9.png\" alt=\"sqlite9\" width=\"439\" height=\"424\" \/><\/a><\/p>\n<p><strong>Function coupling<\/strong><\/p>\n<p>Functions using many other functions\u00a0are very difficult to understand and maintain. It\u2019s recommended \u00a0to minimize the efferent coupling of your functions.<\/p>\n<p>For SQLite very few functions have\u00a0a high efferent coupling:<\/p>\n<p><a href=\"http:\/\/www.codergears.com\/Blog\/wp-content\/uploads\/sqlite10.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-1942\" src=\"http:\/\/www.codergears.com\/Blog\/wp-content\/uploads\/sqlite10.png\" alt=\"sqlite10\" width=\"438\" height=\"521\" \/><\/a><\/p>\n<p><strong>If you can exit a function early, you should.<\/strong><\/p>\n<p>Early exits out of a function, specially through guard clauses at the top of a function are preferred since they simplify the logic further down in the function.<\/p>\n<p>In the SQLite source code this best practice rule is applied for almost all the functions.<\/p>\n<p><strong>Conclusion<\/strong><\/p>\n<p>Exploring some known open source projects is always good to elevate your programming skills, no need to download and build the project, you can just discover the code from GitHub.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>16 years after its first checkin, SQLite is the\u00a0most widely deployed\u00a0database engine in the world. An\u00a0open source project such as this is a good candidate for\u00a0learning how to make your code easy to understand and to maintain. Let\u2019s discover some facts about the SQLite code base, beginning with the following code snippet:<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[7,67,13,10],"class_list":["post-214","post","type-post","status-publish","format-standard","hentry","category-uncategorized","tag-c","tag-c-2","tag-cpp","tag-sqlite"],"_links":{"self":[{"href":"https:\/\/cppdepend.com\/blog\/wp-json\/wp\/v2\/posts\/214","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/cppdepend.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/cppdepend.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/cppdepend.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/cppdepend.com\/blog\/wp-json\/wp\/v2\/comments?post=214"}],"version-history":[{"count":8,"href":"https:\/\/cppdepend.com\/blog\/wp-json\/wp\/v2\/posts\/214\/revisions"}],"predecessor-version":[{"id":1488,"href":"https:\/\/cppdepend.com\/blog\/wp-json\/wp\/v2\/posts\/214\/revisions\/1488"}],"wp:attachment":[{"href":"https:\/\/cppdepend.com\/blog\/wp-json\/wp\/v2\/media?parent=214"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/cppdepend.com\/blog\/wp-json\/wp\/v2\/categories?post=214"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/cppdepend.com\/blog\/wp-json\/wp\/v2\/tags?post=214"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}