Programming Language & Its Applications β C++ Constructs with Objects and Classes, NEC licence examination syllabus (Nepal Engineering Council).
A request to paste the body at the call site instead of jumping to it β trading code size for call overhead.
std::vector element access v[i] is a function call in the source and zero function calls in the compiled binary β the compiler inlined it into a single memory load, which is exactly why C++ programmers can use safe abstractions without paying for them. This is also the whole reason C's #define MAX(a,b) macros exist and why they were a bad idea. Search "zero cost abstraction C++" β inlining is the mechanism that makes that phrase true rather than marketing.#include <iostream>
inline int square(int x) { return x * x; }
inline int max2(int a, int b) { return a > b ? a : b; }
inline double celsius(double f) { return (f - 32) * 5.0 / 9.0; }
/* NOT a good inline candidate - loops, too big */
int sum_to(int n) {
int s = 0;
for (int i = 1; i <= n; i++) s += i;
return s;
}
int main() {
std::cout << "square(7) = " << square(7) << "\n";
std::cout << "max2(12, 30) = " << max2(12, 30) << "\n";
std::cout << "celsius(98.6) = " << celsius(98.6) << "\n";
std::cout << "sum_to(100) = " << sum_to(100) << "\n";
return 0;
}
Output:
square(7) = 49
max2(12, 30) = 30
celsius(98.6) = 37
sum_to(100) = 5050
#include <iostream>
/* THE MACRO WAY - pure text substitution, no type checking */
#define SQ_MACRO(x) ((x) * (x))
#define MAX_MACRO(a, b) ((a) > (b) ? (a) : (b))
/* THE INLINE WAY - a real function, fully type checked */
inline int sq_inline(int x) { return x * x; }
inline int max_inline(int a, int b) { return a > b ? a : b; }
int main() {
int i = 5;
/* TRAP 1: double evaluation of side effects */
i = 5;
std::cout << "SQ_MACRO(i++) = " << SQ_MACRO(i++)
<< " i is now " << i << "\n";
/* expands to ((i++) * (i++)) - i incremented TWICE,
and the order is unspecified: undefined behaviour */
i = 5;
std::cout << "sq_inline(i++) = " << sq_inline(i++)
<< " i is now " << i << "\n";
/* argument evaluated ONCE, then passed. Correct. */
/* TRAP 2: no type checking */
std::cout << "SQ_MACRO(2.5) = " << SQ_MACRO(2.5) << "\n";
std::cout << "sq_inline(2.5) = " << sq_inline(2.5) << "\n";
/* the inline version TRUNCATES 2.5 to 2 - visible,
predictable, and the compiler can warn about it */
return 0;
}
Output (macro line is UB; a typical result):
SQ_MACRO(i++) = 30 i is now 7 <-- 5 * 6, i bumped twice
sq_inline(i++) = 25 i is now 6 <-- correct
SQ_MACRO(2.5) = 6.25
sq_inline(2.5) = 4
SQ_MACRO(i++) is not merely wrong, it is undefined behaviour. Modifying i twice with no sequencing between them means the standard makes no promise at all, so different compilers legitimately print 25, 30 or 36. A bug that changes answer when you change compiler is far worse than one that is simply wrong.
#include <iostream>
class Rectangle {
double w, h;
public:
Rectangle(double w, double h) : w(w), h(h) {}
/* defined INSIDE the class body -> implicitly inline */
double width() const { return w; }
double height() const { return h; }
double area() const { return w * h; }
/* declared here, defined outside */
double perimeter() const;
void describe() const;
};
/* explicit inline when defining outside the class */
inline double Rectangle::perimeter() const {
return 2 * (w + h);
}
/* not inline - has I/O, too big to be worth it */
void Rectangle::describe() const {
std::cout << w << " x " << h
<< " area=" << area()
<< " perim=" << perimeter() << "\n";
}
int main() {
Rectangle r(4.5, 8.0);
r.describe();
std::cout << "width via getter = " << r.width() << "\n";
return 0;
}
Output:
4.5 x 8 area=36 perim=25
width via getter = 4.5
Every member function defined inside the class body is implicitly inline β you do not write the keyword. That is why getters and setters written in the header cost nothing: they compile to the same single memory access as touching the field directly, while still letting you change the implementation later.
constexpr asks the compiler to run the function at compile time entirely, so constexpr int f = factorial(10); puts 3628800 in the binary with no runtime code at all. And link-time optimisation (g++ -flto) lets the compiler inline across .cpp file boundaries, which plain inline never could. Try compiling something with and without -O2 -flto and compare size a.out β seeing the numbers move makes this concrete. Search "constexpr vs inline vs LTO".Create a free account to tick topics off, take notes as you read, watch the video lessons and get a day-by-day study plan built around your exam date.
Loadingβ¦