PageSourceSearch

https://cpp-core-guidelines-docs.vercel.app/_next/static/chunks/pages/source-5699034ac7ea7af6.js

js cpp-core-guidelines-docs.vercel.app collected 2026-10-03 06:35:08 UTC 36,089 bytes, 1 lines download raw bytes

1(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[728],{8056:function(e,n,a){(window.__NEXT_P=window.__NEXT_P||[]).push(["/source",function(){return a(7189)}])},7845:function(e,n,a){"use strict";var i=a(5893);n.Z={github:"https://github.com/isocpp/CppCoreGuidelines",docsRepositoryBase:"https://github.com/isocpp/CppCoreGuidelines/tree/master",titleSuffix:" \u2013 C++",logo:(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)("span",{className:"mr-2 font-extrabold hidden md:inline",children:"C++"}),(0,i.jsx)("span",{className:"text-gray-600 font-normal hidden md:inline",children:"Core Guidelines"})]}),head:(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)("meta",{name:"msapplication-TileColor",content:"#ffffff"}),(0,i.jsx)("meta",{name:"theme-color",content:"#ffffff"}),(0,i.jsx)("meta",{name:"viewport",content:"width=device-width, initial-scale=1.0"}),(0,i.jsx)("meta",{httpEquiv:"Content-Language",content:"en"}),(0,i.jsx)("meta",{name:"description",content:"C++ Core Guidelines"}),(0,i.jsx)("meta",{name:"og:description",content:"C++ Core Guidelines"}),(0,i.jsx)("meta",{name:"twitter:card",content:"summary_large_image"}),(0,i.jsx)("meta",{name:"twitter:image",content:"/og.png"}),(0,i.jsx)("meta",{name:"twitter:site:domain",content:"cpp-core-guidelines-docs.vercel.app"}),(0,i.jsx)("meta",{name:"twitter:url",content:"https://cpp-core-guidelines-docs.vercel.app/"}),(0,i.jsx)("meta",{name:"og:title",content:"C++ Core Guidelines"}),(0,i.jsx)("meta",{name:"og:image",content:"/og.png"}),(0,i.jsx)("meta",{name:"apple-mobile-web-app-title",content:"C++ Core Guidelines"}),(0,i.jsx)("link",{rel:"icon",type:"image/png",sizes:"196x196",href:"/favicon-196x196.png"}),(0,i.jsx)("link",{rel:"icon",type:"image/png",sizes:"32x32",href:"/favicon-32x32.png"}),(0,i.jsx)("link",{rel:"icon",type:"image/png",sizes:"96x96",href:"/favicon-96x96.png"}),(0,i.jsx)("link",{rel:"icon",type:"image/png",sizes:"16x16",href:"/favicon-16x16.png"}),(0,i.jsx)("meta",{name:"msapplication-TileImage",content:"/ms-icon-144x144.png"})]}),search:!0,prevLinks:!0,nextLinks:!0,footer:!0,footerEditLink:"",footerText:(0,i.jsxs)(i.Fragment,{children:["C++ Core Guidelines ",(new Date).getFullYear(),"."]})}},7189:function(e,n,a){"use strict";a.r(n);a(7294);var i=a(3905),l=a(7829),t=a.n(l),o=a(3805),r=a(7845);a(5675);function d(e,n){if(null==e)return{};var a,i,l=function(e,n){if(null==e)return{};var a,i,l={},t=Object.keys(e);for(i=0;i<t.length;i++)a=t[i],n.indexOf(a)>=0||(l[a]=e[a]);return l}(e,n);if(Object.getOwnPropertySymbols){var t=Object.getOwnPropertySymbols(e);for(i=0;i<t.length;i++)a=t[i],n.indexOf(a)>=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(l[a]=e[a])}return l}var m=function(e){return(0,o.withSSG)(t()({filename:"source.mdx",route:"/source",meta:{},pageMap:[{name:"A",route:"/A"},{name:"class",route:"/class"},{name:"concurrency",route:"/concurrency"},{name:"const",route:"/const"},{name:"cpl",route:"/cpl"},{name:"discussion",route:"/discussion"},{name:"enum",route:"/enum"},{name:"errors",route:"/errors"},{name:"expr",route:"/expr"},{name:"faq",route:"/faq"},{name:"functions",route:"/functions"},{name:"glossary",route:"/glossary"},{name:"gsl",route:"/gsl"},{name:"index",route:"/"},{name:"interfaces",route:"/interfaces"},{name:"introduction",route:"/introduction"},{name:"libraries",route:"/libraries"},{name:"meta.json",meta:{index:"Top",introduction:"In: Introduction",philosophy:"P: Philosophy",interfaces:"I: Interfaces",functions:"F: Functions",class:"C: Classes and class hierarchies",enum:"Enum: Enumerations",resource:"R: Resource management",expr:"ES: Expressions and statements",performance:"Per: Performance",concurrency:"CP: Concurrency and parallelism",errors:"E: Error handling",const:"Con: Constants and immutability",templates:"T: Templates and generic programming",cpl:"CPL: C-style programming",source:"SF: Source files",stdlib:"SL: The Standard Library",A:"A: Architectural ideas",not:"NR: Non-Rules and myths",references:"RF: References",profile:"Pro: Profiles",gsl:"GSL: Guidelines support library",naming:"NL: Naming and layout suggestions",faq:"FAQ: Answers to frequently asked questions",libraries:"Appendix A: Libraries",modernizing:"Appendix B: Modernizing code",discussion:"Appendix C: Discussion",tools:"Appendix D: Supporting tools",glossary:"Glossary",unclassified:"To-do: Unclassified proto-rules"}},{name:"modernizing",route:"/modernizing"},{name:"naming",route:"/naming"},{name:"not",route:"/not"},{name:"performance",route:"/performance"},{name:"philosophy",route:"/philosophy"},{name:"profile",route:"/profile"},{name:"references",route:"/references"},{name:"resource",route:"/resource"},{name:"source",route:"/source"},{name:"stdlib",route:"/stdlib"},{name:"templates",route:"/templates"},{name:"tools",route:"/tools"},{name:"unclassified",route:"/unclassified"}]},r.Z))(e)};function s(e){var n=e.components,a=d(e,["components"]);return(0,i.mdx)(m,Object.assign({components:n},a),(0,i.mdx)("h1",null,(0,i.mdx)("a",{href:"#",name:"S-source",parentName:"h1"}
1),"SF: Source files"),(0,i.mdx)("p",null,"Distinguish between declarations (used as interfaces) and definitions (used as implementations).\nUse header files to represent interfaces and to emphasize logical structure."),(0,i.mdx)("p",null,"Source file rule summary:"),(0,i.mdx)("ul",null,(0,i.mdx)("li",{parentName:"ul"},(0,i.mdx)("p",{parentName:"li"},(0,i.mdx)("a",{href:"/source#Rs-file-suffix",parentName:"p"},"(SF.1: Use a ",(0,i.mdx)("inlineCode",{parentName:"a"},".cpp")," suffix for code files and ",(0,i.mdx)("inlineCode",{parentName:"a"},".h")," for interface files if your project doesn't already follow another convention)"))),(0,i.mdx)("li",{parentName:"ul"},(0,i.mdx)("p",{parentName:"li"},(0,i.mdx)("a",{href:"/source#Rs-inline",parentName:"p"},"(SF.2: A ",(0,i.mdx)("inlineCode",{parentName:"a"},".h")," file must not contain object definitions or non-inline function definitions)"))),(0,i.mdx)("li",{parentName:"ul"},(0,i.mdx)("p",{parentName:"li"},(0,i.mdx)("a",{href:"/source#Rs-declaration-header",parentName:"p"},"(SF.3: Use ",(0,i.mdx)("inlineCode",{parentName:"a"},".h")," files for all declarations used in multiple source files)"))),(0,i.mdx)("li",{parentName:"ul"},(0,i.mdx)("p",{parentName:"li"},(0,i.mdx)("a",{href:"/source#Rs-include-order",parentName:"p"},"(SF.4: Include ",(0,i.mdx)("inlineCode",{parentName:"a"},".h")," files before other declarations in a file)"))),(0,i.mdx)("li",{parentName:"ul"},(0,i.mdx)("p",{parentName:"li"},(0,i.mdx)("a",{href:"/source#Rs-consistency",parentName:"p"},"(SF.5: A ",(0,i.mdx)("inlineCode",{parentName:"a"},".cpp")," file must include the ",(0,i.mdx)("inlineCode",{parentName:"a"},".h")," file(s) that defines its interface)"))),(0,i.mdx)("li",{parentName:"ul"},(0,i.mdx)("p",{parentName:"li"},(0,i.mdx)("a",{href:"/source#Rs-using",parentName:"p"},"(SF.6: Use ",(0,i.mdx)("inlineCode",{parentName:"a"},"using namespace")," directives for transition, for foundation libraries (such as ",(0,i.mdx)("inlineCode",{parentName:"a"},"std"),"), or within a local scope (only))"))),(0,i.mdx)("li",{parentName:"ul"},(0,i.mdx)("p",{parentName:"li"},(0,i.mdx)("a",{href:"/source#Rs-using-directive",parentName:"p"},"(SF.7: Don't write ",(0,i.mdx)("inlineCode",{parentName:"a"},"using namespace")," at global scope in a header file)"))),(0,i.mdx)("li",{parentName:"ul"},(0,i.mdx)("p",{parentName:"li"},(0,i.mdx)("a",{href:"/source#Rs-guards",parentName:"p"},"(SF.8: Use ",(0,i.mdx)("inlineCode",{parentName:"a"},"#include")," guards for all ",(0,i.mdx)("inlineCode",{parentName:"a"},".h")," files)"))),(0,i.mdx)("li",{parentName:"ul"},(0,i.mdx)("p",{parentName:"li"},(0,i.mdx)("a",{href:"/source#Rs-cycles",parentName:"p"},"(SF.9: Avoid cyclic dependencies among source files)"))),(0,i.mdx)("li",{parentName:"ul"},(0,i.mdx)("p",{parentName:"li"},(0,i.mdx)("a",{href:"/source#Rs-implicit",parentName:"p"},"(SF.10: Avoid dependencies on implicitly ",(0,i.mdx)("inlineCode",{parentName:"a"},"#include"),"d names)"))),(0,i.mdx)("li",{parentName:"ul"},(0,i.mdx)("p",{parentName:"li"},(0,i.mdx)("a",{href:"/source#Rs-contained",parentName:"p"},"(SF.11: Header files should be self-contained)"))),(0,i.mdx)("li",{parentName:"ul"},(0,i.mdx)("p",{parentName:"li"},(0,i.mdx)("a",{href:"/source#Rs-incform",parentName:"p"},"(SF.12: Prefer the quoted form of ",(0,i.mdx)("inlineCode",{parentName:"a"},"#include")," for files relative to the including file and the angle bracket form everywhere else)"))),(0,i.mdx)("li",{parentName:"ul"},(0,i.mdx)("p",{parentName:"li"},(0,i.mdx)("a",{href:"/source#Rs-namespace",parentName:"p"},"(SF.20: Use ",(0,i.mdx)("inlineCode",{parentName:"a"},"namespace"),"s to express logical structure)"))),(0,i.mdx)("li",{parentName:"ul"},(0,i.mdx)("p",{parentName:"li"},(0,i.mdx)("a",{href:"/source#Rs-unnamed",parentName:"p"},"(SF.21: Don't use an unnamed (anonymous) namespace in a header)"))),(0,i.mdx)("li",{parentName:"ul"},(0,i.mdx)("p",{parentName:"li"},(0,i.mdx)("a",{href:"/source#Rs-unnamed2",parentName:"p"},"(SF.22: Use an unnamed (anonymous) namespace for all internal/non-exported entities)")))),(0,i.mdx)("h3",null,(0,i.mdx)("a",{href:"#",name:"Rs-file-suffix",parentName:"h3"}),"SF.1: Use a ",(0,i.mdx)("inlineCode",{parentName:"h3"},".cpp")," suffix for code files and ",(0,i.mdx)("inlineCode",{parentName:"h3"},".h")," for interface files if your project doesn't already follow another convention"),(0,i.mdx)("h5",null,"Reason"),(0,i.mdx)("p",null,"It's a longstanding convention.\nBut consistency is more important, so if your project uses something else, follow that."),(0,i.mdx)("h5",null,"Note"),(0,i.mdx)("p",null,"This convention reflects a common use pattern:\nHeaders are more often shared with C to compile as both C++ and C, which typically uses ",(0,i.mdx)("inlineCode",{parentName:"p"},".h"),",\nand it's easier to name all headers ",(0,i.mdx)("inlineCode",{parentName:"p"},".h")," instead of having different extensions for just those headers that are intended to be shared with C.\nOn the other hand, implementation files are rarely shared with C and s
1o should typically be distinguished from ",(0,i.mdx)("inlineCode",{parentName:"p"},".c")," files,\nso it's normally best to name all C++ implementation files something else (such as ",(0,i.mdx)("inlineCode",{parentName:"p"},".cpp"),")."),(0,i.mdx)("p",null,"The specific names ",(0,i.mdx)("inlineCode",{parentName:"p"},".h")," and ",(0,i.mdx)("inlineCode",{parentName:"p"},".cpp")," are not required (just recommended as a default) and other names are in widespread use.\nExamples are ",(0,i.mdx)("inlineCode",{parentName:"p"},".hh"),", ",(0,i.mdx)("inlineCode",{parentName:"p"},".C"),", and ",(0,i.mdx)("inlineCode",{parentName:"p"},".cxx"),". Use such names equivalently.\nIn this document, we refer to ",(0,i.mdx)("inlineCode",{parentName:"p"},".h")," and ",(0,i.mdx)("inlineCode",{parentName:"p"},".cpp")," as a shorthand for header and implementation files,\neven though the actual extension might be different."),(0,i.mdx)("p",null,"Your IDE (if you use one) might have strong opinions about suffixes."),(0,i.mdx)("h5",null,"Example"),(0,i.mdx)("pre",null,(0,i.mdx)("code",{className:"language-cpp",parentName:"pre"},"// foo.h:\nextern int a;   // a declaration\nextern void foo();\n\n// foo.cpp:\nint a;   // a definition\nvoid foo() { ++a; }\n")),(0,i.mdx)("p",null,(0,i.mdx)("inlineCode",{parentName:"p"},"foo.h")," provides the interface to ",(0,i.mdx)("inlineCode",{parentName:"p"},"foo.cpp"),". Global variables are best avoided."),(0,i.mdx)("h5",null,"Example, bad"),(0,i.mdx)("pre",null,(0,i.mdx)("code",{className:"language-cpp",parentName:"pre"},"// foo.h:\nint a;   // a definition\nvoid foo() { ++a; }\n")),(0,i.mdx)("p",null,(0,i.mdx)("inlineCode",{parentName:"p"},"#include <foo.h>")," twice in a program and you get a linker error for two one-definition-rule violations."),(0,i.mdx)("h5",null,"Enforcement"),(0,i.mdx)("ul",null,(0,i.mdx)("li",{parentName:"ul"},"Flag non-conventional file names."),(0,i.mdx)("li",{parentName:"ul"},"Check that ",(0,i.mdx)("inlineCode",{parentName:"li"},".h")," and ",(0,i.mdx)("inlineCode",{parentName:"li"},".cpp")," (and equivalents) follow the rules below.")),(0,i.mdx)("h3",null,(0,i.mdx)("a",{href:"#",name:"Rs-inline",parentName:"h3"}),"SF.2: A ",(0,i.mdx)("inlineCode",{parentName:"h3"},".h")," file must not contain object definitions or non-inline function definitions"),(0,i.mdx)("h5",null,"Reason"),(0,i.mdx)("p",null,"Including entities subject to the one-definition rule leads to linkage errors."),(0,i.mdx)("h5",null,"Example"),(0,i.mdx)("pre",null,(0,i.mdx)("code",{className:"language-cpp",parentName:"pre"},"// file.h:\nnamespace Foo {\n    int x = 7;\n    int xx() { return x+x; }\n}\n\n// file1.cpp:\n#include <file.h>\n// ... more ...\n\n // file2.cpp:\n#include <file.h>\n// ... more ...\n")),(0,i.mdx)("p",null,"Linking ",(0,i.mdx)("inlineCode",{parentName:"p"},"file1.cpp")," and ",(0,i.mdx)("inlineCode",{parentName:"p"},"file2.cpp")," will give two linker errors."),(0,i.mdx)("p",null,(0,i.mdx)("strong",{parentName:"p"},"Alternative formulation"),": A ",(0,i.mdx)("inlineCode",{parentName:"p"},".h")," file must contain only:"),(0,i.mdx)("ul",null,(0,i.mdx)("li",{parentName:"ul"},(0,i.mdx)("inlineCode",{parentName:"li"},"#include"),"s of other ",(0,i.mdx)("inlineCode",{parentName:"li"},".h")," files (possibly with include guards)"),(0,i.mdx)("li",{parentName:"ul"},"templates"),(0,i.mdx)("li",{parentName:"ul"},"class definitions"),(0,i.mdx)("li",{parentName:"ul"},"function declarations"),(0,i.mdx)("li",{parentName:"ul"},(0,i.mdx)("inlineCode",{parentName:"li"},"extern")," declarations"),(0,i.mdx)("li",{parentName:"ul"},(0,i.mdx)("inlineCode",{parentName:"li"},"inline")," function definitions"),(0,i.mdx)("li",{parentName:"ul"},(0,i.mdx)("inlineCode",{parentName:"li"},"constexpr")," definitions"),(0,i.mdx)("li",{parentName:"ul"},(0,i.mdx)("inlineCode",{parentName:"li"},"const")," definitions"),(0,i.mdx)("li",{parentName:"ul"},(0,i.mdx)("inlineCode",{parentName:"li"},"using")," alias definitions"),(0,i.mdx)("li",{parentName:"ul"},"???")),(0,i.mdx)("h5",null,"Enforcement"),(0,i.mdx)("p",null,"Check the positive list above."),(0,i.mdx)("h3",null,(0,i.mdx)("a",{href:"#",name:"Rs-declaration-header",parentName:"h3"}),"SF.3: Use ",(0,i.mdx)("inlineCode",{parentName:"h3"},".h")," files for all declarations used in multiple source files"),(0,i.mdx)("h5",null,"Reason"),(0,i.mdx)("p",null,"Maintainability. Readability."),(0,i.mdx)("h5",null,"Example, bad"),(0,i.mdx)("pre",null,(0,i.mdx)("code",{className:"language-cpp",parentName:"pre"},'// bar.cpp:\nvoid bar() { cout << "bar\\n"; }\n\n// foo.cpp:\nextern void bar();\nvoid foo() { bar(); }\n')),(0,i.mdx)("p",null,"A maintainer of ",(0,i.mdx)("inlineCode",{parentName:"p"},"bar")," cannot find all declarations of ",(0,i.mdx)("inlineCode",{parentName:"p"},"bar")," if its type needs changing.\nThe user of ",(0,i.mdx)("inlineCode",{parentName:"p"},"bar")," cannot know if the interface used is complete and correct. At best, error messages come (late) from the linker."),(0,i.mdx)("h5",null,"Enforcement"),(0,i.mdx)("ul",null,(0,i.mdx)("li",{parentName:"ul"},"Flag declarations of entities in other source files not placed in a ",(0,i.mdx)("inlineCode",{parentName:"li"},".h"),".")),(0,i.mdx)("h3",null,(0,i.mdx)("a",{href:"#",name:"Rs-include-order",parentName:"h3"}),"SF.4: Include ",(0,i.mdx)("inlineCode",{parentName:"h3"},".h")," files before other declarations in a file"),(0,i.mdx)("h5",null,"Reason"),(0,i.mdx)("p",null,"Minim
1ize context dependencies and increase readability."),(0,i.mdx)("h5",null,"Example"),(0,i.mdx)("pre",null,(0,i.mdx)("code",{className:"language-cpp",parentName:"pre"},"#include <vector>\n#include <algorithm>\n#include <string>\n\n// ... my code here ...\n")),(0,i.mdx)("h5",null,"Example, bad"),(0,i.mdx)("pre",null,(0,i.mdx)("code",{className:"language-cpp",parentName:"pre"},"#include <vector>\n\n// ... my code here ...\n\n#include <algorithm>\n#include <string>\n")),(0,i.mdx)("h5",null,"Note"),(0,i.mdx)("p",null,"This applies to both ",(0,i.mdx)("inlineCode",{parentName:"p"},".h")," and ",(0,i.mdx)("inlineCode",{parentName:"p"},".cpp")," files."),(0,i.mdx)("h5",null,"Note"),(0,i.mdx)("p",null,"There is an argument for insulating code from declarations and macros in header files by ",(0,i.mdx)("inlineCode",{parentName:"p"},"#including")," headers ",(0,i.mdx)("em",{parentName:"p"},"after"),' the code we want to protect\n(as in the example labeled "bad").\nHowever'),(0,i.mdx)("ul",null,(0,i.mdx)("li",{parentName:"ul"},"that only works for one file (at one level): Use that technique in a header included with other headers and the vulnerability reappears."),(0,i.mdx)("li",{parentName:"ul"},'a namespace (an "implementation namespace") can protect against many context dependencies.'),(0,i.mdx)("li",{parentName:"ul"},"full protection and flexibility require modules.")),(0,i.mdx)("p",null,(0,i.mdx)("strong",{parentName:"p"},"See also"),":"),(0,i.mdx)("ul",null,(0,i.mdx)("li",{parentName:"ul"},(0,i.mdx)("a",{href:"http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/n4592.pdf",parentName:"li"},"Working Draft, Extensions to C++ for Modules")),(0,i.mdx)("li",{parentName:"ul"},(0,i.mdx)("a",{href:"http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0141r0.pdf",parentName:"li"},"Modules, Componentization, and Transition"))),(0,i.mdx)("h5",null,"Enforcement"),(0,i.mdx)("p",null,"Easy."),(0,i.mdx)("h3",null,(0,i.mdx)("a",{href:"#",name:"Rs-consistency",parentName:"h3"}),"SF.5: A ",(0,i.mdx)("inlineCode",{parentName:"h3"},".cpp")," file must include the ",(0,i.mdx)("inlineCode",{parentName:"h3"},".h")," file(s) that defines its interface"),(0,i.mdx)("h5",null,"Reason"),(0,i.mdx)("p",null,"This enables the compiler to do an early consistency check."),(0,i.mdx)("h5",null,"Example, bad"),(0,i.mdx)("pre",null,(0,i.mdx)("code",{className:"language-cpp",parentName:"pre"},"// foo.h:\nvoid foo(int);\nint bar(long);\nint foobar(int);\n\n// foo.cpp:\nvoid foo(int) { /* ... */ }\nint bar(double) { /* ... */ }\ndouble foobar(int);\n")),(0,i.mdx)("p",null,"The errors will not be caught until link time for a program calling ",(0,i.mdx)("inlineCode",{parentName:"p"},"bar")," or ",(0,i.mdx)("inlineCode",{parentName:"p"},"foobar"),"."),(0,i.mdx)("h5",null,"Example"),(0,i.mdx)("pre",null,(0,i.mdx)("code",{className:"language-cpp",parentName:"pre"},"// foo.h:\nvoid foo(int);\nint bar(long);\nint foobar(int);\n\n// foo.cpp:\n#include <foo.h>\n\nvoid foo(int) { /* ... */ }\nint bar(double) { /* ... */ }\ndouble foobar(int);   // error: wrong return type\n")),(0,i.mdx)("p",null,"The return-type error for ",(0,i.mdx)("inlineCode",{parentName:"p"},"foobar")," is now caught immediately when ",(0,i.mdx)("inlineCode",{parentName:"p"},"foo.cpp")," is compiled.\nThe argument-type error for ",(0,i.mdx)("inlineCode",{parentName:"p"},"bar")," cannot be caught until link time because of the possibility of overloading, but systematic use of ",(0,i.mdx)("inlineCode",{parentName:"p"},".h")," files increases the likelihood that it is caught earlier by the programmer."),(0,i.mdx)("h5",null,"Enforcement"),(0,i.mdx)("p",null,"???"),(0,i.mdx)("h3",null,(0,i.mdx)("a",{href:"#",name:"Rs-using",parentName:"h3"}),"SF.6: Use ",(0,i.mdx)("inlineCode",{parentName:"h3"},"using namespace")," directives for transition, for foundation libraries (such as ",(0,i.mdx)("inlineCode",{parentName:"h3"},"std"),"), or within a local scope (only)"),(0,i.mdx)("h5",null,"Reason"),(0,i.mdx)("p",null,(0,i.mdx)("inlineCode",{parentName:"p"},"using namespace")," can lead to name clashes, so it should be used sparingly.\nHowever, it is not always possible to qualify every n
1ame from a namespace in user code (e.g., during transition)\nand sometimes a namespace is so fundamental and prevalent in a code base, that consistent qualification would be verbose and distracting."),(0,i.mdx)("h5",null,"Example"),(0,i.mdx)("pre",null,(0,i.mdx)("code",{className:"language-cpp",parentName:"pre"},"#include <string>\n#include <vector>\n#include <iostream>\n#include <memory>\n#include <algorithm>\n\nusing namespace std;\n\n// ...\n")),(0,i.mdx)("p",null,"Here (obviously), the standard library is used pervasively and apparently no other library is used, so requiring ",(0,i.mdx)("inlineCode",{parentName:"p"},"std::")," everywhere\ncould be distracting."),(0,i.mdx)("h5",null,"Example"),(0,i.mdx)("p",null,"The use of ",(0,i.mdx)("inlineCode",{parentName:"p"},"using namespace std;")," leaves the programmer open to a name clash with a name from the standard library"),(0,i.mdx)("pre",null,(0,i.mdx)("code",{className:"language-cpp",parentName:"pre"},"#include <cmath>\nusing namespace std;\n\nint g(int x)\n{\n    int sqrt = 7;\n    // ...\n    return sqrt(x); // error\n}\n")),(0,i.mdx)("p",null,"However, this is not particularly likely to lead to a resolution that is not an error and\npeople who use ",(0,i.mdx)("inlineCode",{parentName:"p"},"using namespace std")," are supposed to know about ",(0,i.mdx)("inlineCode",{parentName:"p"},"std")," and about this risk."),(0,i.mdx)("h5",null,"Note"),(0,i.mdx)("p",null,"A ",(0,i.mdx)("inlineCode",{parentName:"p"},".cpp")," file is a form of local scope.\nThere is little difference in the opportunities for name clashes in an N-line ",(0,i.mdx)("inlineCode",{parentName:"p"},".cpp")," containing a ",(0,i.mdx)("inlineCode",{parentName:"p"},"using namespace X"),",\nan N-line function containing a ",(0,i.mdx)("inlineCode",{parentName:"p"},"using namespace X"),",\nand M functions each containing a ",(0,i.mdx)("inlineCode",{parentName:"p"},"using namespace X"),"with N lines of code in total."),(0,i.mdx)("h5",null,"Note"),(0,i.mdx)("p",null,(0,i.mdx)("a",{href:"/source#Rs-using-directive",parentName:"p"},"(Don't write ",(0,i.mdx)("inlineCode",{parentName:"a"},"using namespace")," at global scope in a header file)"),"."),(0,i.mdx)("h5",null,"Enforcement"),(0,i.mdx)("p",null,"Flag multiple ",(0,i.mdx)("inlineCode",{parentName:"p"},"using namespace")," directives for different namespaces in a single source file."),(0,i.mdx)("h3",null,(0,i.mdx)("a",{href:"#",name:"Rs-using-directive",parentName:"h3"}),"SF.7: Don't write ",(0,i.mdx)("inlineCode",{parentName:"h3"},"using namespace")," at global scope in a header file"),(0,i.mdx)("h5",null,"Reason"),(0,i.mdx)("p",null,"Doing so takes away an ",(0,i.mdx)("inlineCode",{parentName:"p"},"#include"),"r's ability to effectively disambiguate and to use alternatives. It also makes ",(0,i.mdx)("inlineCode",{parentName:"p"},"#include"),"d headers order-dependent as they might have different meaning when included in different orders."),(0,i.mdx)("h5",null,"Example"),(0,i.mdx)("pre",null,(0,i.mdx)("code",{className:"language-cpp",parentName:"pre"},'// bad.h\n#include <iostream>\nusing namespace std; // bad\n\n// user.cpp\n#include "bad.h"\n\nbool copy(/*... some parameters ...*/);    // some function that happens to be named copy\n\nint main()\n{\n    copy(/*...*/);    // now overloads local ::copy and std::copy, could be ambiguous\n}\n')),(0,i.mdx)("h5",null,"Note"),(0,i.mdx)("p",null,"An exception is ",(0,i.mdx)("inlineCode",{parentName:"p"},"using namespace std::literals;"),". This is necessary to use string literals\nin header files and given ",(0,i.mdx)("a",{href:"http://eel.is/c++draft/over.literal",parentName:"p"},"the rules")," - users are required\nto name their own UDLs ",(0,i.mdx)("inlineCode",{parentName:"p"},'operator""_x')," - they will not collide with the standard library."),(0,i.mdx)("h5",null,"Enforcement"),(0,i.mdx)("p",null,"Flag ",(0,i.mdx)("inlineCode",{parentName:"p"},"using namespace")," at global scope in a header file."),(0,i.mdx)("h3",null,(0,i.mdx)("a",{href:"#",name:"Rs-guards",parentName:"h3"}),"SF.8: Use ",(0,i.mdx)("inlineCode",{parentName:"h3"},"#include")," guards for all ",(0,i.mdx)("inlineCode",{parentName:"h3"},".h")," files"),(0,i.mdx)("h5",null,"Reason"),(0,i.mdx)("p",null,"To avoid files being ",(0,i.mdx)("inlineCode",{parentName:"p"},"#include"),"d several times."),(0,i.mdx)("p",null,"In order to avoid include guard collisions, do not just name the guard after the filename.\nBe sure to also include a key and good differentiator, such as the name of library or component\nthe header file is part of."),(0,i.mdx)("h5",null,"Example"),(0,i.mdx)("pre",null,(0,i.mdx)("code",{className:"language-cpp",parentName:"pre"},"// file foobar.h:\n#ifndef LIBRARY_FOOBAR_H\n#define LIBRARY_FOOBAR_H\n// ... declarations ...\n#endif // LIBRARY_FOOBAR_H\n")),(0,i.mdx)("h5",null,"Enforcement"),(0,i.mdx)("p",null,"Flag ",(0,i.mdx)("inlineCode",{parentName:"p"},".h")," files without ",(0,i.mdx)("inlineCode",{parentName:"p"},"#include")," guards."),(0,i.mdx)("h5",null,"Note"),(0,i.mdx)("p",null,"Some implementations offer vendor extensions like ",(0,i.mdx)("inlineCode",{parentName:"p"},"#pragma once")," as alternative to include guards.\nIt is not standard and it is not portable. It injects the hosting machine's filesystem semantics\ninto your program, in addition to locking you down to a vendor.\nOur recommendation is to write in ISO C++: See ",(0,i.mdx)("a",{href:"/philosophy#Rp-Cplusplus",parentName:"p"},"(rule P.2)"),"."),(0,i.mdx)("h3",null,(0,i.mdx)("a",{href:"#",name:"Rs-cycles",parentName:"h3"}),"SF.9: Avoid cyclic dependencies among source files"),(0,i.mdx)("h5",null,"Reason"),(0,i.mdx)("p",null,"Cycles complicate comprehension and slow down compilation. They also\ncomplicate conversion to use language-supported modules (when they become\navailable)."),(0,i.mdx)("h5",null,"Note"),(0,i.mdx)("p",null,"Eliminate cycles; don't just break them with ",(0,i.mdx)("inlineCode",{parentName:"p"},"#include")," guards."),(0,i.mdx)("h5",null,"Example, bad"),(0,i.mdx)("pre",null,(0,i.mdx)("code",{className:"language-cpp",parentName:"pre"},'// file1.h:\n#include "file2.h"\n\n// file2.h:\n#include "file3.h"\n\n// file3.h:\n#include "file1.h"\n')),(0,i.mdx)("h5",null,"Enforcement"),(0,i.mdx)("p",null,"Flag all cycles."),(0,i.mdx)("h3",null,(0,i.mdx)("a",{href:"#",name:"Rs-implicit",parentName:"h3"}),"SF.10: Avoid dependencies on implicitly ",(0,i.mdx)("inlineCode",{parentName:"h3"},"#include"),"d names"),(0,i.mdx)("h5",null,"Reason"),(0,i.mdx)("p",null,"Avoid surprises.\nAvoid having to change ",(0,i.mdx)("inlineCode",{parentName:"p"},"#include"),"s if an ",(0,i.mdx)("inlineCode",{parentName:"p"},"#include"),"d header changes.\nAvoid accidentally becoming dependent on implementation details and logically separate entities included in a header."),(0,i.mdx)("h5",null,"Example, bad"),(0,i.mdx)("pre",null,(0,i.mdx)("code",{className:"language-cpp",parentName:"pre"},'#include <iostream>\nusing namespace std;\n\nvoid use()\n{\n    string s;\n    cin >> s;               // fine\n    getline(cin, s);        // error: getline() not defined\n    if (s == "surprise") {  // error == not defined\n        // ...\n    }\n}\n')),(0,i.mdx)("p",null,(0,i.mdx)("inlineCode",{parentName:"p"},"<iostream>")," exposes the definition of ",(0,i.mdx)("inlineCode",{parentName:"p"},"std::string"),' ("why?" makes for a fun trivia question),\nbut it is not required to do so by transitively including the entire ',(0,i.mdx)("inlineCode",{parentName:"p"},"<string>")," header,\nresulting in the popular beginner question \"why doesn't ",(0,i.mdx)("inlineCode",{parentName:"p"},"getline(cin,s);"),' work?"\nor even an occasional "',(0,i.mdx)("inlineCode",{parentName:"p"},"string"),"s cannot be compared with ",(0,i.mdx)("inlineCode",{parentName:"p"},"=="),'").'),(0,i.mdx)("p",null,"The solution is to explicitly ",(0,i.mdx)("inlineCode",{parentName:"p"},"#include <string>"),":"),(0,i.mdx)("h5",null,"Example, good"),(0,i.mdx)("pre",null,(0,i.mdx)("code",{className:"language-cpp",parentName:"pre"},'#include <iostream>\n#include <string>\nusing namespace std;\n\nvoid use()\n{\n    string s;\n    cin >> s;               // fine\n    getline(cin, s);        // fine\n    if (s == "surprise") {  // fine\n        // ...\n    }\n}\n')),(0,i.mdx)("h5",null,"Note"),(0,i.mdx)("p",null,"Some headers exist exactly to collect a set of consistent declarations from a variety of headers.\nFor example:"),(0,i.mdx)("pre",null,(0,i.mdx)("code",{className:"language-cpp",parentName:"pre"},"// basic_std_lib.h:\n\n#include <string>\n#include <map>\n#include <iostream>\n#include <random>\n#include <vector>\n")),(0,i.mdx)("p",null,"a user can now get that set of declarations with a single ",(0,i.mdx)("inlineCode",{parentName:"p"},"#include")),(0,i.mdx)("pre",null,(0,i.mdx)("code",{className:"language-cpp",parentName:"pre"},'#include "basic_std_lib.h"\n')),(0,i.mdx)("p",null,"This rule against implicit inclusion is not meant to prevent such deliberate aggregation."),(0,i.mdx)("h5",null,"Enforcement"),(0,i.mdx)("p",null,'Enforcement would require some knowledge about what in a header is meant to be "exported" to users and what is there to enable implementation.\nNo really good solution is possible until we have modules.'),(0,i.mdx)("h3",null,(0,i.mdx)("a",{href:"#",name:"Rs-contained",parentName:"h3"}),"SF.11: Header files should be self-contained"),(0,i.mdx)("h5",null,"Reason"),(0,i.mdx)("p",null,"Usability, headers should be simple to use and work when included on their own.\nHeaders should encapsulate the functionality they provide.\nAvoid clients of a header having to manage that header's depen
1dencies."),(0,i.mdx)("h5",null,"Example"),(0,i.mdx)("pre",null,(0,i.mdx)("code",{className:"language-cpp",parentName:"pre"},'#include "helpers.h"\n// helpers.h depends on std::string and includes <string>\n')),(0,i.mdx)("h5",null,"Note"),(0,i.mdx)("p",null,"Failing to follow this results in difficult to diagnose errors for clients of a header."),(0,i.mdx)("h5",null,"Note"),(0,i.mdx)("p",null,"A header should include all its dependencies. Be careful about using relative paths because C++ implementations diverge on their meaning."),(0,i.mdx)("h5",null,"Enforcement"),(0,i.mdx)("p",null,"A test should verify that the header file itself compiles or that a cpp file which only includes the header file compiles."),(0,i.mdx)("h3",null,(0,i.mdx)("a",{href:"#",name:"Rs-incform",parentName:"h3"}),"SF.12: Prefer the quoted form of ",(0,i.mdx)("inlineCode",{parentName:"h3"},"#include")," for files relative to the including file and the angle bracket form everywhere else"),(0,i.mdx)("h5",null,"Reason"),(0,i.mdx)("p",null,"The ",(0,i.mdx)("a",{href:"http://eel.is/c++draft/cpp.include",parentName:"p"},"standard")," provides flexibility for compilers to implement\nthe two forms of ",(0,i.mdx)("inlineCode",{parentName:"p"},"#include")," selected using the angle (",(0,i.mdx)("inlineCode",{parentName:"p"},"<>"),") or quoted (",(0,i.mdx)("inlineCode",{parentName:"p"},'""'),") syntax. Vendors take\nadvantage of this and use different search algorithms and methods for specifying the include path."),(0,i.mdx)("p",null,"Nevertheless, the guidance is to use the quoted form for including files that exist at a relative path to the file containing the ",(0,i.mdx)("inlineCode",{parentName:"p"},"#include")," statement (from within the same component or project) and to use the angle bracket form everywhere else, where possible. This encourages being clear about the locality of the file relative to files that include it, or scenarios where the different search algorithm is required. It makes it easy to understand at a glance whether a header is being included from a local relative file versus a standard library header or a header from the alternate search path (e.g. a header from another library or a common set of includes)."),(0,i.mdx)("h5",null,"Example"),(0,i.mdx)("pre",null,(0,i.mdx)("code",{className:"language-cpp",parentName:"pre"},'// foo.cpp:\n#include <string>                // From the standard library, requires the <> form\n#include <some_library/common.h> // A file that is not locally relative, included from another library; use the <> form\n#include "foo.h"                 // A file locally relative to foo.cpp in the same project, use the "" form\n#include "foo_utils/utils.h"     // A file locally relative to foo.cpp in the same project, use the "" form\n#include <component_b/bar.h>     // A file in the same project located via a search path, use the <> form\n')),(0,i.mdx)("h5",null,"Note"),(0,i.mdx)("p",null,"Failing to follow this results in difficult to diagnose errors due to picking up the wrong file by incorrectly specifying the scope when it is included. For example, in a typical case where the ",(0,i.mdx)("inlineCode",{parentName:"p"},'#include ""')," search algorithm might search for a file existing at a local relative path first, then using this form to refer to a file that is not locally relative could mean that if a file ever comes into existence at the local relative path (e.g. the including file is moved to a new location), it will now be found ahead of the previous include file and the set of includes will have been changed in an unexpected way."),(0,i.mdx)("p",null,"Library creators should put their headers in a folder and have clients include those files using the relative path ",(0,i.mdx)("inlineCode",{parentName:"p"},"#include <some_library/common.h>")),(0,i.mdx)("h5",null,"Enforcement"),(0,i.mdx)("p",null,"A test should identify whether headers referenced via ",(0,i.mdx)("inlineCode",{parentName:"p"},'""')," could be referenced with ",(0,i.mdx)("inlineCode",{parentName:"p"},"<>"),"."),(0,i.mdx)("h3",null,(0,i.mdx)("a",{href:"#",name:"Rs-namespace",parentName:"h3"}),"SF.20: Use ",(0,i.mdx)("inlineCode",{parentName:"h3"},"namespace"),"s to express logical structure"),(0,i.mdx)("h5",null,"Reason"),(0,i.mdx)("p",null,"???"),(0,i.mdx)("h5",null,"Example"),(0,i.mdx)("pre",null,(0,i.mdx)("code",{className:"language-cpp",parentName:"pre"},"???\n")),(0,i.mdx)("h5",null,"Enforcement"),(0,i.mdx)("p",null,"???"),(0,i.mdx)("h3",null,(0,i.mdx)("a",{href:"#",name:"Rs-unnamed",parentName:"h3"}),"SF.21: Don't use an unnamed (anonymous) namespace in a header"),(0,i.mdx)("h5",null,"Reason"),(0,i.mdx)("p",null,"It is almost always a bug to mention an unnamed namespace in a header file."),(0,i.mdx)("h5",null,"Example"),(0,i.mdx)("pre",null,(0,i.mdx)("code",{className:"language-cpp",parentName:"pre"},"// file foo.h:\nnamespace\n{\n    const double x = 1.234;  // bad\n\n    double foo(double y)     // bad\n    {\n        return y + x;\n    }\n}\n\nnamespace Foo\n{\n    const double x = 1.234; // good\n\n    inline double foo(double y)        // good\n    {\n        return y + x;\n    }\n}\n")),(0,i.mdx)("h5",null,"Enforcement"),(0,i.mdx)("ul",null,(0,i.mdx)("li",{parentName:"ul"},"Flag any use of an anonymous namespace in a header file.")),(0,i.mdx)("h3",null,(0,i.mdx)("a",{href:"#",name:"Rs-unnamed2",parentName:"h3"}),"SF.22: Use an unnamed (anonymous) namespace for all internal/non-exported entities"),(0,i.mdx)("h5",null,"Reason"),(0,i.mdx)("p",null,'Nothing external 
1can depend on an entity in a nested unnamed namespace.\nConsider putting every definition in an implementation source file in an unnamed namespace unless that is defining an "external/exported" entity.'),(0,i.mdx)("h5",null,"Example; bad"),(0,i.mdx)("pre",null,(0,i.mdx)("code",{className:"language-cpp",parentName:"pre"},"static int f();\nint g();\nstatic bool h();\nint k();\n")),(0,i.mdx)("h5",null,"Example; good"),(0,i.mdx)("pre",null,(0,i.mdx)("code",{className:"language-cpp",parentName:"pre"},"namespace {\n    int f();\n    bool h();\n}\nint g();\nint k();\n")),(0,i.mdx)("h5",null,"Example"),(0,i.mdx)("p",null,'An API class and its members can\'t live in an unnamed namespace; but any "helper" class or function that is defined in an implementation source file should be at an unnamed namespace scope.'),(0,i.mdx)("pre",null,(0,i.mdx)("code",{className:"language-cpp",parentName:"pre"},"???\n")),(0,i.mdx)("h5",null,"Enforcement"),(0,i.mdx)("ul",null,(0,i.mdx)("li",{parentName:"ul"},"???")))}s.isMDXComponent=!0,n.default=s}},function(e){e.O(0,[58,774,888,179],(function(){return n=8056,e(e.s=n);var n}));var n=e.O();_N_E=n}]);

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.