{"id":15047904,"url":"https://github.com/banach-space/cpp-tutor","last_synced_at":"2025-04-06T23:16:51.051Z","repository":{"id":88814832,"uuid":"158110032","full_name":"banach-space/cpp-tutor","owner":"banach-space","description":"Code examples for tutoring modern C++","archived":false,"fork":false,"pushed_at":"2025-02-04T19:37:12.000Z","size":111,"stargazers_count":93,"open_issues_count":0,"forks_count":9,"subscribers_count":8,"default_branch":"main","last_synced_at":"2025-03-30T22:10:02.078Z","etag":null,"topics":["cplusplus-11","cplusplus-14","cplusplus-17","cpp-tutor","memory-leaks"],"latest_commit_sha":null,"homepage":"","language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/banach-space.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","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":"2018-11-18T17:41:12.000Z","updated_at":"2025-03-16T04:48:33.000Z","dependencies_parsed_at":"2025-02-28T05:05:50.704Z","dependency_job_id":"5bd924d1-2925-4e33-b5c3-6b7b6f3c4a73","html_url":"https://github.com/banach-space/cpp-tutor","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/banach-space%2Fcpp-tutor","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/banach-space%2Fcpp-tutor/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/banach-space%2Fcpp-tutor/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/banach-space%2Fcpp-tutor/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/banach-space","download_url":"https://codeload.github.com/banach-space/cpp-tutor/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247563935,"owners_count":20958971,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","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":["cplusplus-11","cplusplus-14","cplusplus-17","cpp-tutor","memory-leaks"],"created_at":"2024-09-24T21:05:55.225Z","updated_at":"2025-04-06T23:16:51.033Z","avatar_url":"https://github.com/banach-space.png","language":"C++","funding_links":[],"categories":[],"sub_categories":[],"readme":"cpp-tutor\n=========\n[![Apple Silicon](https://github.com/banach-space/cpp-tutor/actions/workflows/apple-silicon.yml/badge.svg)](https://github.com/banach-space/cpp-tutor/actions/workflows/apple-silicon.yml)\n[![x86-Ubuntu](https://github.com/banach-space/cpp-tutor/actions/workflows/x86-ubuntu.yml/badge.svg)](https://github.com/banach-space/cpp-tutor/actions/workflows/x86-ubuntu.yml)\n\nCode examples for tutoring modern C++.\n\n### tl;dr\nStudy by reading the source files, building the executable and running them to\nsee the output.\n\nSummary\n-------\nThe intent of this tutorial is to give a quick overview of some of the most\nimportant and interesting features of C++, and to do so in a form of complete\nand self-contained examples. It focuses on modern C++ (C++11/C++14/C++17), but\nthere are also some pre C++11 and C-specific examples for comparison. It's by\nno means complete - quite the contrary. It aim is to be:\n  * **Concise**: the examples are short, yet complete - to the point. There's a\n    source file implementing the `main` function for each [items](#items) and\n    you can study it in complete isolation from other items.\n  * **Selective**: the examples emphasise features and corner cases most likely\n    encountered when _just_ starting with modern C++. They focus on key points\n    rather then presenting the complete picture. Less is more.\n  * **Clear**: the examples sacrifice code quality in favour of code clarity\n    and readability, e.g. in some cases there's more comments than code. Also,\n    see the [disclaimer](#disclaimer)\n\nIt is assumed that you already know some basic C++ and are familiar with\nobject-oriented programming. These code samples will be helpful if you're\nswitching to C++ from a different object oriented language, are preparing for\nan interview, or, like myself, are mentoring junior C++ developers.\n\nDisclaimer\n----------\nThe examples presented here are meant to highlight (and sometimes exploit) the\nspecifics and quirks of the language. To this end, the presented examples may\nexhibit undefined or implementation specific behaviour, or implement solutions\nthat are against good coding practices. This is done for educational purposes\nonly and always thoroughly documented.\n\nThis repository is self-published and has not been peer-reviewed in the\ntraditional sense.\n\nStatus\n------\n**WORK-IN-PROGRESS**\n\nPlatform Support\n----------------\nThe only requirement for **cpp-tutor** is a C++17 compliant compiler and\n`CMake-3.4.3` or newer. It is supported on Linux, Mac OS X and Windows, and is\nregularly tested against the following configurations (extracted from the CI\nfiles: `.travis.yml` and `appveyor.yml`):\n  * Linux Ubuntu 16.04 (GCC-7 and LLVM-7)\n  * Windows (Visual Studio 2015)\n  * Mac OS X 10.13 (Apple LLVM 10)\n\nPlease refer to the CI logs (links at the top of the page) for reference\nsetups.\n\nUsage\n-----\nThe [items](#items) covered in this tutorial are independent and you can be\nstudied in any order that works for you. Once you choose an item that's of\ninterest to you, go through the links and code samples available below. Next,\n[build](#build-instructions) and run it.  Most executables print to `stdout`.\nMake sure that you understand where the output comes from, what it means and\nthat it matches the comments in the code.\n\nSome examples implement undefined behaviour, contain compiler errors or code\nthat leads to memory leaks. Such _broken_ or _problematic_ parts of the code\nare guarded off with preprocessor symbolic constants:\n  * `COMPILATION_ERROR`\n  * `MEMORY_LEAK`\n  * `DANGLING_REF_OR_PTR`\n  * `RUNTIME_ERROR` \n\nBe default all symbolic constants are undefined and hence there are neither\ncompilation errors nor memory leaks. Play around by defining them (one at a\ntime), recompiling and re-running the examples. Make sure that the generated\noutput (or compiler errors) makes sense. Comments in the corresponding source\nfiles might be instrumental in understanding those.\n\nRemember to re-build and re-run the examples  _before_ and _after_\ndefining `MEMORY_LEAK`/`DANGLING_REF_OR_PTR`/`RUNTIME_ERROR` (defining\n`COMPILATION_ERROR` will prevent the code from compiling, so it's not really\nrelevant here).\n\n### Memory leaks\nIf you're developing on Linux, you can use [Valgrind](http://valgrind.org/) to\nget a better grasp of memory leaks implemented in some of the examples, e.g.:\n```bash\n$ cd \u003cbuild_dir\u003e\n$ valgrind smart_pointers\n```\n(`\u003cbuild_dir\u003e` is the build directory used when [building](#build-instructions)\nthe project).\n\nOn other platforms, you can use\n[AddressSanitizer](https://clang.llvm.org/docs/AddressSanitizer.html). This has\nalready been integrated for you, but currently only for\n[clang](https://clang.llvm.org/) and [gcc](https://gcc.gnu.org/).  In order to\nuse the address sanitizer, set the [build type](#build-types) to `ASAN`, and\nrun your example like this:\n```bash\n$ ASAN_OPTIONS=detect_leaks=1 strings_pool\n```\n\n### Runtime errors\nThe special case of runtime errors requires additional explanation. In most\ncases the code guarded with `RUNTIME_ERRORS` exhibits undefined behaviour, and\nas a result anything can happen. Although often the actual behaviour can be\npredicted with a good amount of accuracy (because compilers, runtimes and\noperating systems are relatively stable), do bare in mind that the output\nwill depend on the system that you use.\n\nBuild Instructions\n------------------\nIt is assumed that **cpp-tutor** will be built in `\u003cbuild-dir\u003e` and that the\ntop-level source directory is `\u003csource-dir\u003e`. For brevity, the build\ninstructions are presented for Linux only.\n\nFirst, you will need to clone Google Test inside `\u003csource-dir\u003e`:\n```bash\n$ cd \u003csource_dir\u003e\n$ git clone https://github.com/google/googletest.git\n```\n\nNext, you can build all the examples as follows:\n```bash\n$ cd \u003cbuild-dir\u003e\n$ cmake -DCT_LLVM_INSTALL_DIR=\u003cllvm-install-dir\u003e \u003csource_dir\u003e\n$ make\n```\nThis will generate all the targets implemented for this project. If you want to\n(re-)build a particular example, run:\n```bash\n$ make \u003cexample_name\u003e\n```\n\n### Build types\nSet the `CMAKE_BUILD_TYPE` variable to:\n  * `Release` to generate optimised code\n  * `ASAN` to generate build unoptimised code, with plenty of good debug info and\n    configured to be run with address sanitzer\n\n### Switching between C++ standards\nThe default C++ standard for the whole project is set to C++17. In order to\nrebuild using `C++11` or `C++17`, use `CMAKE_CXX_STANDARD`. For example, to\nbuild in `C++17` mode:\n```bash\n$ cd \u003cbuild-dir\u003e\n$ cmake -DCMAKE_CXX_STANDARD=17 \u003csource_dir\u003e\n$ make\n```\nThis will be very helpful when looking at how certain constructs have evolved\nwith the language.\n\n### Disabled code\nAs explained [elsewhere](#usage) in this README.md, some of the examples\ncontain code disabled with preprocessor symbols. In order to enable one of\nsuch blocks, define the corresponding preprocessor symbol by re-running CMake\nlike this:\n```bash\n$ cmake -D\u003cPREPROCESSOR_SYMBOL\u003e=1 .\n```\n\nin which `PREPROCESSOR_SYMBOL` is one of:\n  * `COMPILATION_ERROR`\n  * `MEMORY_LEAK`\n  * `DANGLING_REF_OR_PTR`\n  * `RUNTIME_ERROR` \n\nThis will update `\u003cbuild_dir\u003e/include/cppt_ag.hpp`, the CMake auto-generated\nheader file that will be updated with the required definition. Next, re-build\nand re-run your example.\n\nItems\n-----\nThe items covered in this tutorial so far (with some relevant links):\n1. [Strings](http://cs.stmarys.ca/~porter/csc/ref/c_cpp_strings.html) (even more\n   [strings](https://embeddedartistry.com/blog/2017/7/24/stdstring-vs-c-strings))\n   * C-strings vs `std::string` vs `std::string_view`\n   * the underlying data-representation\n   * SSO ([Short String Optimisation](https://akrzemi1.wordpress.com/2014/04/14/common-optimizations/))\n   * `std::string` vs `std::string_view` (performance comparison)\n   * source files:\n     * `strings_1_main.cpp` and `strings_reverse.cpp`\n     * `strings_2_main.cpp`\n     * `strings_3_main.cpp`\n2. [Dynamic memory allocation](https://en.wikipedia.org/wiki/C_dynamic_memory_allocation)\n   * all forms of `new` and `delete` (for plain datatypes and classes)\n   * dynamic array of dynamic objects (a.k.a. 2-dimensional dynamical arrays)\n   * memory leaks caused by mismatch in `new` and `delete`\n   * deep vs shallow copy\n   * a basic memory manager implemented in terms of `placement new`\n   * source files:\n     * `pointers_main.cpp`\n     * `deep_vs_shallow.{hpp|cpp}`, `deep_vs_shallow_main.cpp`\n     * `strings_pool_main.cpp`, `strings_pool.{cpp|hpp}`, `tests_strings_pool.cpp`,\n3. [C++ Unit testing](https://github.com/google/googletest)\n   * GTest and test fixtures\n   * embedding GTest tests into the build system\n   * source files:\n     * `cpp_tutor_ut_main.cpp`, `CMakeLists.txt`, `tests_strings_object.cpp`, `tests_strings.cpp`\n4. [Smart pointers](https://docs.microsoft.com/en-us/cpp/cpp/smart-pointers-modern-cpp?view=vs-2017)\n   * `std::unique_ptr`, `std::shared_ptr`, `std::weak_ptr`\n   * `std::make_unqiue` and `std::make_shared`\n   * source files:\n     * `smart_pointers_main.cpp`\n5. [L-value and R-value](https://eli.thegreenplace.net/2011/12/15/understanding-lvalues-and-rvalues-in-c-and-c/)\n   * l-value vs r-value\n   * l-value reference vs l-value to const reference vs r-value reference\n   * `std::move` vs `std::forward`\n   * source files:\n     * `rvalue_vs_lvalue_main.cpp`\n6. [Move semantics](https://www.cprogramming.com/c++11/rvalue-references-and-move-semantics-in-c++11.html)\n   * move constructor and move assign operator\n   * source files\n     * `memory_block.cpp`, `memory_block_main.cpp`\n7. [Return Value Optimisation](https://en.wikipedia.org/wiki/Copy_elision#Return_value_optimization)\n   * (N)RVO\n   * guaranteed copy elision (C++17)\n   * source files:\n     * `rvo_main.cpp`\n8. [New kewords in C++11](https://www.codeproject.com/Articles/570638/Ten-Cplusplus11-Features-Every-Cplusplus-Developer)\n   and [beyond](https://github.com/AnthonyCalandra/modern-cpp-features)\n   * `const` vs `constexpr`, `nullptr`, `auto`, `decltype`\n   * source files:\n     * `const_vs_constexpr_main.cpp`, `null_vs_nullptr_main.cpp`,\n       `auto_vs_decltype_main.cpp`\n9. [Explicit type conversion](https://www.learncpp.com/cpp-tutorial/4-4a-explicit-type-conversion-casting/) (a.k.a. casting):\n    * explicit vs implicit type conversion\n    * C vs C++ style casts (`static_cast`, `dynamic_cast`, `reinterpret_cast`,\n      `const_cast`)\n    * source files:\n      * `type_casting_main.cpp`\n10. [Initialization in modern C++](https://www.youtube.com/watch?v=SCoewvXablk)\n   (is [bonkers](https://blog.tartanllama.xyz/initialization-is-bonkers/))\n    * init values for variables with automatic and static storage duration\n    * types of initialization (direct, copy, value, list)\n    * brace elistion in list initialization\n    * initializing aggregate types\n    * various gotchas when using initilizer lists\n    * source files:\n      * `init_stack_vs_global_vars_main.cpp`, `init_aggregate_main.cpp`,\n        `init_brace_elision_main.cpp`, `init_types_of_main.cpp`,\n        `init_list_gotchas_main.cpp`\n\nLicense\n--------\nThe MIT License (MIT)\n\nCopyright (c) 2018-2019 Andrzej Warzyński\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of\nthis software and associated documentation files (the \"Software\"), to deal in\nthe Software without restriction, including without limitation the rights to\nuse, copy, modify, merge, publish, distribute, sublicense, and/or sell copies\nof the Software, and to permit persons to whom the Software is furnished to do\nso, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbanach-space%2Fcpp-tutor","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbanach-space%2Fcpp-tutor","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbanach-space%2Fcpp-tutor/lists"}