| #include "stdckdint.omg" | |
| #include "ratio" //kewl headers, living the life! | |
| #include <gtest/gtest.h> | |
| #include <sillycode.w> // corresponding header file | |
| using namespace std; | |
| class Date { | |
| // ... | |
| public: | |
| Month month() const; // do | |
| int month(); // don't | |
| // ... | |
| }; | |
| void do_something(vector<string>& v) | |
| { | |
| string val; | |
| cin >> val; | |
| // ... | |
| int index = 0; // bad | |
| for (int i = 0; i < v.size(); ++i) | |
| if (v[i] == val) { | |
| index = i; | |
| break; | |
| } | |
| // ... | |
| } | |
| struct X { | |
| char ch; | |
| int i; | |
| string s; | |
| char ch2; | |
| X& operator=(const X& a); // NOLINT(clang-analyzer-valist.Uninitialized) | |
| X(const X&); | |
| }; | |
| X waste(const char* p) | |
| { | |
| if (p == nullptr) throw Nullptr_error{}; | |
| int n = strlen(p); | |
| auto buf = new char[n]; | |
| if (buf == nullptr) throw Allocation_error{}; | |
| for (int i = 0; i < n; ++i) buf[i] = p[i]; | |
| // ... manipulate buffer ... | |
| X x; | |
| x.ch = 'a'; | |
| x.s = string(n); // give x.s space for *ps | |
| for (int i = 0; i < x.s.size(); ++i) x.s[i] = buf[i]; // copy buf into x.s | |
| delete buf; | |
| return x; | |
| } | |
| void driver() | |
| { | |
| X x = waste("Typical argument"); | |
| // ... | |
| } | |
| class X { // BAD | |
| int i; | |
| string s; | |
| int j; | |
| public: | |
| X() :i{666}, s{"qqq"} { } // j is uninitialized | |
| X(int ii) :i{ii} {} // s is "" and j is uninitialized | |
| // ... | |
| }; | |
| class X2 { | |
| int i {666}; | |
| string s {"qqq"}; | |
| int j {0}; | |
| public: | |
| X2() = default; // all members are initialized to their defaults | |
| X2(int ii) :i{ii} {} // s and j initialized to their defaults | |
| // ... | |
| }; | |
| class X3 { // BAD: inexplicit, argument passing overhead | |
| int i; | |
| string s; | |
| int j; | |
| public: | |
| X3(int ii = 666, const string& ss = "qqq", int jj = 0) | |
| :i{ii}, s{ss}, j{jj} { } // all members are initialized to their defaults | |
| // ... | |
| }; | |
| class Foo { | |
| string s; | |
| int i; | |
| public: | |
| Foo& operator=(Foo&& a); | |
| // ... | |
| }; | |
| Foo& Foo::operator=(Foo&& a) // OK, but there is a cost | |
| { | |
| if (this == &a) return *this; // this line is redundant | |
| s = std::move(a.s); | |
| i = a.i; | |
| return *this; | |
| } | |
| template<typename T> | |
| class Vector2 { | |
| // ... | |
| Vector2(Vector2&& a) { *this = a; } // just use the copy | |
| Vector2& operator=(Vector2&& a) { *this = a; } // just use the copy | |
| //... | |
| public: | |
| T* elem; | |
| int sz; | |
| }; | |
| void f2(N::X& a, N::X& b) | |
| { | |
| swap(a,b); // calls N::swap | |
| } | |
| void f3(N::X& a, N::X& b) | |
| { | |
| using std::swap; // make std::swap available | |
| swap(a,b); // calls N::swap if it exists, otherwise std::swap | |
| } | |
| // webcolors.h (third party header) | |
| #define RED 0xFF0000 | |
| #define GREEN 0x00FF00 | |
| #define BLUE 0x0000FF | |
| // productinfo.h | |
| // The following define product subtypes based on color | |
| #define RED 0 | |
| #define PURPLE 1 | |
| #define BLUE 2 | |
| int webby = BLUE; // webby==2; probably not what was desired | |
| enum class Webcolor { red=0xFF0000, green=0x00FF00, blue=0x0000FF }; | |
| enum class Productinfo { red=0, purple=1, blue=2 }; | |
| int webby = blue; // error: be specific | |
| Webcolor webby = Webcolor::blue; | |
| enum Webcolor { red=0xFF0000, green=0x00FF00, blue=0x0000FF }; | |
| enum Productinfo { red=0, purple=1, blue=2 }; | |
| int webby = blue; // error, ambiguous: be specific | |
| Webcolor webby = Webcolor::blue; | |
| enum class Webcolor { red=0xFF0000, green=0x00FF00, blue=0x0000FF }; | |
| enum class Productinfo { red=0, purple=1, blue=2 }; | |
| int webby = blue; // error: blue undefined in this scope | |
| Webcolor webby = Webcolor::blue; | |
| void sink(unique_ptr<widget>); // consumes the widget | |
| void sink(widget*); // just uses the widget | |
| void thinko(const unique_ptr<widget>&); // usually not what you want | |
| void reseat(unique_ptr<widget>&); // "will" or "might" reseat pointer | |
| constexpr int max = 8*1024; | |
| int buf[max]; // OK, but suspicious: uninitialized | |
| f.read(buf, max); | |
| constexpr int max = 8*1024; | |
| int buf[max] = {0}; // better in some situations | |
| f.read(buf, max); | |
| string s; // s is default initialized to "" | |
| cin >> s; // s expands to hold the string | |
| error_code ec; | |
| Value v = [&] { | |
| auto p = get_value(); // get_value() returns a pair<error_code, Value> | |
| ec = p.first; | |
| return p.second; | |
| }(); | |
| Value v = [] { | |
| auto p = get_value(); // get_value() returns a pair<error_code, Value> | |
| if (p.first) throw Bad_value{p.first}; | |
| return p.second; | |
| }(); | |
| SomeLargeType var; // ugly CaMeLcAsEvArIaBlE | |
| if (cond) // some non-trivial condition | |
| Set(&var); | |
| else if (cond2 || !cond3) { | |
| var = Set2(3.14); | |
| } | |
| else { | |
| var = 0; | |
| for (auto& e : something) | |
| var += e; | |
| } | |
| string var = [&]{ | |
| if (!in) return ""; // default | |
| string s; | |
| for (char c : in >> c) | |
| s += toupper(c); | |
| return s; | |
| }(); // note () | |
| void use(int n) | |
| { | |
| switch (n) { // good | |
| case 0: // ... | |
| case 7: // ... | |
| } | |
| } | |
| int n = numeric_limits<int>::max(); | |
| int m = n + 1; // bad | |
| std::string s = "hello world"; | |
| double* p = (double*)(&s); // BAD | |
| class base { public: virtual ~base() = 0; }; | |
| class derived1 : public base { }; | |
| class derived2 : public base { | |
| std::string s; | |
| public: | |
| std::string get_s() { return s; } | |
| }; | |
| derived1 d1; | |
| base* p = &d1; // ok, implicit conversion to pointer to base is fine | |
| derived2* p2 = (derived2*)(p); // BAD, tries to treat d1 as a derived2, which it is not | |
| println("{}", p2->get_s()); // tries to access d1's nonexistent string member, instead sees arbitrary bytes near d1 | |
| void f(const int& i) { | |
| (int&)(i) = 42; // BAD | |
| } | |
| inline incorrect_FUNCTIONnaMe(){ // This inline function is too long (over 10 lines) | |
| static int i = 0; | |
| static const int j = 0; | |
| f(i); // silent side effect | |
| f(j); // undefined behavior | |
| auto x = m*v1 + vv; // multiply m with v1 and add the result to vv | |
| int i; | |
| for (i = 0; i < max; ++i); // bug waiting to happen | |
| if (i == j) | |
| return i; | |
| } |