Purpose: making programs easier to understand by breaking up into concise functions
export if function is for use by other modules (declare it from modle interface file while the function's definition can either be in same module interface file or in so-called module implementation file)Definition (i.e. function prototypes, function headers): represent how the function can be accessed (not the code behind it).
void foo(int i, char c);void foo(int i, char c) {
cout format("the value of i and c: {} {}", i, c) << endl;
}foo(8, 'a');)auto add(int x, int y) { return x + y; }
return statements in the body to deduce this - if there are multiple they must all resolve to same typereturn in the function must be non-recursive call__func__ contains name of current function
cout << format("Entering function {}", __func__) << endl;Good Example
int addNumbers(int a, int b) { return a + b; }
double addNumbers(double a, double b) { return a + b; }
Def'n: mechanism to add optional and/or vendor-specific info to source code
[[nodiscard]]: let the compiler issue a warning when a function's return value is ignored[[nodiscard("msg")]] int func() available since C++20Example
[[nodiscard]] int func() { return 42; }
int main() { func(); } // warning: discarding return value of function with 'nodiscard' attribute
[[maybe_unused]]: suppress compiler warnings when something is unusedExample
int func(int param1, [[maybe_unused]] int param2) { return 42; }
// suppresses:
// warning C4100: 'param2': unreferenced formal parameter
[[noreturn]]: never returns control to the call site - avoids compiler giving warnings (these are usually used for termination)Example
[[noreturn]] void forceProgramTermination() { std::exit(1);}
// Suppresses warning C4715: 'isFeatureLicensed': not all control paths return a value
[[deprecated]]:mark sth deprecated - still usable but discouraged. Issues a compiler warning[[deprecated("Unsafe method, please use xyz")]] void func();[[likely]] and [[unlikely]] (C++20 and above): help compiler optimizing code by marking branches of if and switch statements according to how liekly is that branch will be takenExample
int value { /* ... */ };
if (value > 11) [[unlikely]] {
// Do something ...
} else {
// Do something else...
}
switch (value) {
[[likely]] case 1:
// Do something ...
break;
case 2:
// Do something...
break;
[[unlikely]] case 12:
// Do something...
break;
default:
// Optional default handling...
break;
}