# C++ guidelines - Prefer private (or static) functions over anonymous scopes `{ ... }`. - Use `//` comments, not `/* */` - Use `long` for sizes and indices, not `int` or `size_t` - Use spaces, not tabs. - Functions which take an `ostream &` argument should not modify stream state in the caller. ` - If a class `X` derives from `std::enable_shared_from_this`, then its constructor(s() must be protected, and the class must define `create()` static method(s) that return `shared_ptr`. ## ksgpu Uses the `ksgpu` helper library, especially the Array class (ksgpu/Array.hpp), memory managment (ksgpu/mem_utils.hpp), and xassert macros (ksgpu/xassert.hpp, see below). CRITIAL: please complain if you don't see the ksgpu library in the cursor/claude workspace. ## xassert macros The following macros are similar to `assert()`, but throw an exception instead of terminating: ``` xassert(cond); // throw exception unless bool(cond)==true xassert_eq(x,y); // throw exception unless x==y xassert_divisible(x,y); // throw exception unless (x % y) == 0 // also: xassert_ne(), xassert_lt(), xassert_le(), xassert_gt(), xassert_ge() // Throw exception unless 'arr' (type ksgpu::Array) has shape {3,4,5}. // IMPORTANT: note parentheses around the shape -- these are needed to compile! xassert_shape_eq(arr, ({3,4,5})); ``` The exception text shows the file/line (like regular `assert()`), plus values of the arguments `x` and `y`. In the case of `xassert_shape_eq()`, both array shapes are shown. Please use `xassert()` for argument-checking and error-checking, unless there is a reason to create a more verbose error message. For example: ``` void f(int x, int y, int z) { // Example 1: you should replace this by xassert_eq(x,y), since the xassert_eq() error message // contains the same information as the message below (namely, numerical values of x and y). if (x != y) { stringstream ss; ss << "f(): expected x==y, got x=" << x << ", y=" << y; throw runtime_error(ss.str()); } // Example 2: you should not replace this by xassert_lt(x+y,z), since the xassert_eq() error message // contains less information than the message below (which shows x,y,z individually) if ((x+y) >= z) { stringstream ss; ss << "f(): expected (x+y) < z, got x=" << x << ", y=" << ", z=" << z; throw runtime_error(ss.str()); } // Example 3: you should replace this by xassert_shape_eq(arr, ({M,N})), since the xassert_shape_eq() // message contains more information (namely, the actual and expected array shapes). if ((arr.ndim != 2) || (arr.shape[0] != x) && (arr.shape[1] != y)) { stringstream ss; ss << "f(): expected shape (x,y) = (" << x << "," << y << "), got " << arr.shape_str(); throw runtime_error(ss.str()); } } ```