{"id":15598000,"url":"https://github.com/ibob/karisik-coding-style","last_synced_at":"2026-03-19T03:29:28.886Z","repository":{"id":247965131,"uuid":"827197329","full_name":"iboB/karisik-coding-style","owner":"iboB","description":"The Karisik coding style for C++ and C projects","archived":false,"fork":false,"pushed_at":"2025-03-17T15:23:01.000Z","size":12,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-10-14T08:24:40.111Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":null,"has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"unlicense","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/iboB.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-07-11T07:27:57.000Z","updated_at":"2025-03-17T15:23:05.000Z","dependencies_parsed_at":"2025-03-17T16:28:03.012Z","dependency_job_id":"8b96e151-b9c7-492a-b8c6-0b84fb80e7d5","html_url":"https://github.com/iboB/karisik-coding-style","commit_stats":null,"previous_names":["ibob/karisik-coding-style"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/iboB/karisik-coding-style","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/iboB%2Fkarisik-coding-style","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/iboB%2Fkarisik-coding-style/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/iboB%2Fkarisik-coding-style/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/iboB%2Fkarisik-coding-style/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/iboB","download_url":"https://codeload.github.com/iboB/karisik-coding-style/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/iboB%2Fkarisik-coding-style/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28615564,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-20T21:52:42.722Z","status":"ssl_error","status_checked_at":"2026-01-20T21:52:20.513Z","response_time":117,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-10-03T01:25:52.541Z","updated_at":"2026-01-20T22:03:00.829Z","avatar_url":"https://github.com/iboB.png","language":null,"funding_links":[],"categories":[],"sub_categories":[],"readme":"﻿# Karisik Coding Style\n\nKarisik is a coding style for C++ (and to some extent C). The name is a simplified version of the Turkish word \"karışık,\" which means \"mixed,\" and it truly is a mixed bag of styles.\n\nThis document was initially written in 2012 and has been modified many times since. It will likely be updated in the future.\n\n## Philosophy\n\nThe Karisik style prioritizes readability, maintainability, and developer productivity. It encourages flexibility while providing clear guidelines to avoid common pitfalls.\n\nThe goal of this style is to make development easier and symbols visually distinct.\n\n\u003e [!NOTE]\n\u003e **Use judgment!**\n\u003e This is not a strict set of rules but a guideline.\n\u003e If you think something is better done differently, do it differently (and preferably document it).\n\n## Some Terminology\n\n### Symbol Name Cases\n\n- **C case** (aka snake case): `this_is_c_case` - all lowercase with words separated by underscores.\n- **All Caps case**: `THIS_IS_CAPS_CASE` - all caps with words separated by underscores.\n- **Pascal case**: `ThisIsPascalCase` - first letter is capitalized, and each word begins with a capital letter.\n- **Camel case**: `thisIsCamelCase` - like Pascal case but the first letter is lowercase.\n- **K\u0026R case**: `thisisknrcase` - all lowercase with no separators between words; abbreviations are encouraged.\n- **Mixed case**: `This_Is_MixedCase` - like Pascal case but with some words separated by underscores.\n- **Hyphen case**: `this-is-hyphen-case` - all lowercase with words separated by hyphens (not used for symbol names).\n- **Crazy case**: `thisIS_Crazy_case_pR0baB1y` - everything else.\n\n### File types:\n\n* **source files** - files supplied to the compiler. Note that some other documents refer to these as *compilation units*, and use the term *source files* to group them with headers too.\n* **header files** - files included in source files *and have include guards*\n* **inline files** - files included in source files *and do not have include guards*. It is usually not expected by library users to manually include inline files, though exceptions exist.\n\n## Standard-library-like code\n\nSome code is undoubtedly standard-library-like. It might be a custom string, or a custom container. It is acceptable to write such code the way the standard library is written: Everything in C case. (Take a look at the [Boost Design and Programming requirements](https://www.boost.org/development/requirements.html#Design_and_Programming) for a bit more detail)\n\nAs a rule of thumb, imagine the code actually being a part of the standard library. If you don't find yourself shocked by the idea, then it's likely a good idea to use the standard-library-like style, and disregard the rest of this document.\n\nFor example my library [itlib](https://github.com/iboB/itlib) follows Karisik even though it's entirely in C case.\n\n## Files and directories\n\n### Directory structure\n\n* For executables add all source and header files files in a directory called `code`. It's much easier to have related files in one place.\n* For libraries either add all files in `code` *or* separate public headers in `include` and private headers and source files in `src`\n    * Which one to choose is up to you. If you envision writing complex install scripts for the library and ship it closed-source, then you life would be a bit easier doing this if you have separate public and private directories. Otherwise, don't bother.\n* Repo subdirectories are in Hyphen case or K\u0026R case. They are much easier to navigate in the terminal this way.\n    * Subdirectories of `code`, `include` and `src` are in K\u0026R case, presumably matching namespaces or library names contained within.\n* For libraries in the headers directory (`code` or `include`) add an additional subdirectory with the library's name. Thus including files from the library will be also be namespaced `#include \u003clib/file.h\u003e` and the risk of clashes will be minimal.\n* Separate logically related groups of files into subdirectories (and optionally namespaces)\n    * If a library's source is splint into `src` and `include` you will sadly have to duplicate the tree in `src/` and `include/\u003clibrary name\u003e/`.\n\n### Files\n\n* C++\n    * File names are in Pascal case\n    * Header files have a `.hpp` extension\n    * Source files have a `.cpp` extension\n    * Inline files have a `.inl` extension (`.ipp` is also acceptable but follow-through, don't mix `.inl` and `.ipp`)\n* C\n    * File names are in C case\n    * Header files have a `.h` extension\n    * Source files have a `.c` extension\n    * Inline files have a `.i` extension (`inl` is also acceptable but follow-through, don't mix `.i` and `.inl`)`\n* In certain cases there are files which extend existing ones. Separate the extension with dot + Camel case. For example if you want I/O operations for a class `Foo` you would have `Foo.hpp` and `Foo.io.hpp`\n* Prefix non-project files with a letter/word + `hyphen` (making them Crazy case at times). This is help you navigate to files (Ctrl-P-style) easier and easily distinguish them from the main project counterparts. Using Hyphen case for special files with no counterparts is acceptable\n    * Prefix tests with `t-`, as in `t-core.cpp` or `t-MyClass.cpp`\n    * Prefix examples with `e-`, as in `e-MyClass.cpp` or `e-async-io.cpp`\n    * Prefix benchmarks with `b-`, as in `b-MyClass-io.cpp` or `b-object-construction.cpp`\n* Executables and libraries:\n    * Name output executables and libraries with hyphen-case\n    * Prefix special executables with first the project/library name and then with the type, as in `myproject-test-core` or `myproject-example-async-io`\n        * Here Crazy case may also come into play if it's related to a specific symbol in the code, as in `myplib-test-MyClass`.\n\n## Header files\n\n* For include guards **just use `#pragma once`**\n* **Header files must be self-contained**. This means that you don't need to include anything specific in order to include a header file without compilation errors. Even if you use precompiled headers, follow this rule.\n* **Don't pollute the global namespace**. In C++ everything else must be declared in namespaces. Macros and C symbols must be prefixed with library or subsystem name.\n* **Prefer forward declarations instead of includes where possible.** This helps compilation times a lot.\n\n## Spacing\n\n### Use spaces and never tabs\n\nModern code is often viewed through browsers. Even though some viewers (ie GitHub) can be configured to display tabs at a given width, most only display them as 8 spaces, and even if the configuration is possible, the default is still 8. Our opinion is that **8 spaces is excessive for indentation**.\n\n**The code always looks the same in every editor**. Tab proponents usually say that the opposite is precisely what makes tab a good option: different users can adjust the indentation size according to their taste. Our opinion is that having the code always look the same is more valuable. Sometimes for readability certain alignments need to be made which tend to look different on different tab widths. This making the code even less readable than its non-aligned version. Spaces are safe.\n\n### Indent with four spaces\n\nThere is no particular rationale here. Four is the closest to an \"industry standard\" that we have for C++. We like four. It's perfectly adequate.\n\n### Don't align types and variables in a table-like manner\n\nSome people do this religiously and we must cringe at how something acceptable like this:\n\n```c++\nint    count = 0;\nfloat  speed = 3;\nstring name;\n```\n\n... turns into this monstrosity:\n\n```c++\nint                                count = 0;\nfloat                              speed = 3;\nstd::map\u003cstd::string, std::string\u003e name2addr;\n```\n\nPlus when is this being used? If those are local variables in a function, this is not C. Variables are declared before being used, not at the beginning of the function. If those are fields in a struct it's more often than not you tend to have comments above them. Comments above make this look even worse:\n\n```c++\n// count of instances\nint                                count = 0;\n\n// speed in meters per second\n// also my eyes are bleeding\nfloat                              speed = 3;\n\n// names mapped to addresses for the members\nstd::map\u003cstd::string, std::string\u003e name2addr;\n```\n\nAnother problem with this is that sometimes you have to add a new variable to a list like this which has a longer type. Then you cry because you have to change 100 lines of code. Just for adding one new variable!\n\nThis is not to say, however, that you should never align code in a table-like manner! It's only variable declarations we're talking about. And as usual, use judgement and don't overcommit to this.\n\n### Leave a space between a keyword and open parenthesis and no space otherwise\n\nIt's rare when a code is read without syntax highlighting, but in these rare cases this space makes keywords sand out more.\n\n```c++\nif (x)\nwhile (y)\nfor (a;b;c)\n```\n\n```c++\nfunc(a, b, c);\nfunctionalObject(x, y, z); // here we have an overloaded operator () - still a function call\nMACRO(foo, bar)\n```\n\n## Naming\n\n### Namespaces are a single word of up to 8 characters in K\u0026R case\n\nNamespaces are names which appear in the code often. Very, very often, as you don't want to pollute the global namespace from a header. Some files can contain the same namespace name tens of times. Because of this, long namespace names are bad juju. They clutter the source code. We don't like them. Nobody likes them. Keep them short. Single short(-ish?) word, no underscores, no nothing.\n\n```c++\nnamespace engine {} // cool\nnamespace url {} // abbreviations are fine\nnamespace frj {} // if \"frj\" means something in this domain, then sure\nnamespace bignum {} // portmanteaus are fine\n```\n\n**Read below for pseudo enum-classes, which is an exceptions to this**\n\n### Type names are nouns in Pascal case\n\n```c++\nclass Application;\nstruct FontData;\nenum class TextAlignment;\n```\n\n### Public member variables don't have a prefix and are in Camel case\n```c++\nint foo;\nstd::string barBaz;\n```\n\n### Private and protected member variables have a `m_` prefix\n\nThe main motivation for the prefix is code completion. When you type `m_`, you will get suggestions of member-variables for the current scope. It's very useful. Some people suggest a single underscore prefix, but too many things in the global namespace of a typical C++ source file begin with underscores. The completion suggestions will get polluted by that.\n\n```c++\nprivate:\n    float m_length;\n    std::vector\u003cVertex\u003e m_renderVertices;\n```\n\n### Member-functions are verbs in Camel case\n\n```c++\nvoid moveTo(Position pos);\nvoid reset();\n```\n\nFunctions are typed much more often than types. Having them with lower case is just easier to type and works with all code-completion tools out there.\n\n### ... except getters which are\n\nFirst of all, we define getters as zero-cost const member functions which return either an object by value or by const reference and feature a single return of a single value. Those should be **nouns in camel case** and always inline on a single line.\n\n```c++\nfloat length() const { return m_length; }\nconst std::vector\u003cVector\u003e\u0026 renderVertices() const { return m_renderVertices; }\n```\n\nNote that other inline functions may exist and other getter-like functions as well which don't fit the above definitions. For example `std::vector::size` typically returns `end - begin`. With this style guide this function would look like this:\n\n```c++\nsize_t getSize() const\n{\n    return m_end - m_begin;\n}\n```\n\nWhether to have separate declarations and definitions for inline functions is a matter of choice. If you do separate them, make sure to mark them as such at the declaration.\n\n```c++\ninline size_t getSize() const; // defined below\n```\n\n### Local variables and argument names are either K\u0026R case or camelCase\n\nAgain the main rationale here is convenience. Use judgement.\n\n```c++\nuint32_t xspaces = countSpaces(Axis::x);\nfloat unicodeText = toUnicode(utf8Text);\n```\n\nIt's perfectly acceptable to use single letter names or abbreviations for counters or unique instances. Use judgement.\n\n### Constants are in Mixed case\n\nThis makes them stand out from other symbols. Contants are unusual. Also for cases where multiple constants are related prefix them with the relation and group the rest\n\n```c++\nconstexpr int Max_Length = 132;\nconst int Text_MaxLength = 42;\nconst std::string Text_DefaultFont = \"Arial\";\n```\n\n### Enum members are either in K\u0026R case or Mixed case\n\nThis is again to save typing and condense the code where possible. Use judgement.\n\n```c++\nenum class Axis {\n    x,\n    y,\n    z\n};\n\n// but\n\nenum Axis {\n    Axis_X,\n    Axis_Y,\n    Axis_Z\n};\n\n// or even\n\nenum class Operation {\n    Add,\n    Multiply,\n    Fused_Multiply_Add,\n};\n```\n\n## Scoping\n\n### All scopes must be surrounded with braces on new lines\n\nAll scopes with braces... experience has taught us that this is a good idea even when it's not needed for correctness. It's just easier to see and harder to make accidental bugs.\n\nOn new lines? Again this is just a bit easier to use. During debugging or experimentation you may find yourself commenting out ifs (equivalent to `if (true)`\n\n```c++\nif (something)\n{\n    foo();\n}\n```\n\n... becomes:\n\n```c++\n// if (something)\n{\n    foo();\n}\n```\n\n### ... except if-return and if-throw statements\n\n`if-return` and `if-throw` are quite popular to write and comment out. It's much easier to comment-out a single line. Also if you get used to it, you can easily identify single-line `if`-s as an `if-return` instance. So:\n\n```c++\nif (!valid) return -1;\n```\n\n### ... and empty statements\n\nEmpty scopes can either be written on a single line `{}` with no spaces, or in the case of `while` and `for` completely omitted.\n\n```c++\nwhile (*a++ == *b++);\nfor (int i=0; func(i); ++i);\nvoid noop() {}\nstruct tag : public tagged {};\n```\n\n### ... and single line return-val functions\n\n...as covered above.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fibob%2Fkarisik-coding-style","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fibob%2Fkarisik-coding-style","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fibob%2Fkarisik-coding-style/lists"}