C++ Bits: Post 3 The sizeof Trap: Why Is Your Class Bigger Than You Think? Quick what's the output of the code in the image given below? If you said both are 4... you just fell into one of C++'s most classic interview traps. sizeof(A) is indeed 4 bytes , just one int, nothing else. But sizeof(B)? On most 64-bit systems, it's 16 bytes. Not 4. Not even 12. Where did the extra 12 bytes come from? The moment you add the virtual keyword, the compiler secretly injects a hidden pointer called the vptr (virtual pointer) into every object of that class. This vptr points to a vtable , a per-class lookup table of function pointers that enables runtime polymorphism. On a 64-bit system, that hidden pointer is 8 bytes. So your object is now 4 (int) + 8 (vptr) = 12 bytes. But wait , the compiler also adds padding to align the object to an 8-byte boundary. So 12 becomes 16. Let's break it down: → class A: [int x = 4B] → Total: 4 bytes → class B: [vptr = 8B] + [int x = 4B] + [padding = 4B] → Total: 16 bytes One keyword. Triple the memory. And if you're allocating millions of objects, that difference isn't trivial ,it's a design decision. This is exactly why some performance-critical codebases (game engines, embedded systems) deliberately avoid virtual functions. The overhead isn't the virtual call , it's the memory bloat across millions of objects. Next time someone says "just make it virtual," remember: polymorphism isn't free. The compiler is quietly billing you 8 bytes per object, plus padding. What's the sneakiest sizeof result you've encountered in an interview or codebase? Let's hear it below. #CPP #Cplusplus #SoftwareEngineering #TechTrivia #Programming #BackendDevelopment
C++ sizeof Trap: Virtual Functions and Memory Bloat
More Relevant Posts
-
You wrote the code correctly. The compiler deleted it. This is undefined behavior in C. And it is more dangerous than most people realize. Here is a real example: int *ptr = get_pointer(); int value = *ptr; // UB if ptr is NULL if (ptr == NULL) return; // optimizer may remove this *ptr = 42; Looks safe. Right? The compiler sees it differently. It thinks: "If ptr were NULL, dereferencing it would be undefined behavior. Since I assume undefined behavior never happens, ptr is never NULL. Therefore the check is useless." So it removes the check entirely. Your safety net is gone. Silently. Without warning. This is not a bug in the compiler. This is C working exactly as designed. Undefined behavior means the compiler can do anything, including things that make your code look correct until it suddenly isn't. The three most dangerous types: ☠️ Signed integer overflow: the result is not what you expect, and the compiler assumes it never happens ☠️ Out-of-bounds access: sometimes works, sometimes corrupts memory, always unpredictable ☠️ Null pointer dereference: can corrupt memory silently instead of crashing The scariest part? It often works fine in debug mode. It breaks in release build. Because optimizations are what expose it. In embedded and automotive systems, this is not academic. It is a safety risk. Have you ever been hit by undefined behavior without knowing it at first? #CProgramming #SystemsProgramming #EmbeddedSystems #UndefinedBehavior #LowLevelProgramming #AutomotiveSoftware #SoftwareEngineering #CodeWithMo --- Ⓜ️🌐
To view or add a comment, sign in
-
-
STOP using the Cluster module for heavy computation. You’re literally burning memory 🔥 Most developers still confuse this: 👉 Cluster = scaling requests 👉 Worker Threads = crunching data Here’s the reality: Cluster module: • Spawns multiple processes • Each process has its own memory (V8 instance) • Great for handling high traffic (I/O) • ❌ Terrible for CPU-heavy work (wastes RAM) Worker Threads: • Runs inside a single process • Shares memory using ArrayBuffer • Built for parallel computation • ✅ Perfect for CPU-intensive tasks (image processing, encryption, data crunching) 💡 Rule of thumb: Use Cluster to scale users Use Worker Threads to scale performance If you're using Cluster for heavy calculations… you're solving the wrong problem. #NodeJS #JavaScript #BackendDevelopment #WebDevelopment #SoftwareEngineering #Programming #TechTips #SystemDesign #Performance #Developers
To view or add a comment, sign in
-
-
“No one reads compiler output, so no one will review LLM code.” Yeah, no. Compilers are deterministic transformations over a formally-defined programming language. They guarantee that your program’s semantics will be remain intact through the transformation. You learn this as a CS major. LLMs don’t give you any such guarantees. They produce plausible code with no guarantees that it actually does what’s intended. So we try to compensate that by having LLMs verify their own output using tools. But if the verification itself is driven by another probabilistic system with no guarantees, how do you trust that the verification is sound? So the only way this works is if the verification layer is grounded in something deterministic you as a human can trust: tests, type systems, static analysis, etc (all of which needs to be independently verified). Without any of this, someone still has to read the code or you accept that bugs will slip through to production.
To view or add a comment, sign in
-
👉 Question-55 A strong understanding of double pointers, dynamic memory allocation, pointer arithmetic, and function behavior is essential in systems programming and embedded development. Assume: --> int = 4 bytes --> Default compiler behavior 👉 What will be the output of the following code❓ #include <stdio.h> #include <stdlib.h> void modify(int **p) { *p = (int *)realloc(*p, sizeof(int) * 3); (*p)[2] = (*p)[0] + (*p)[1]; (*p)[0] = 100; } int main() { int *arr = (int *)malloc(sizeof(int) * 2); arr[0] = 10; arr[1] = 20; int **ptr = &arr; modify(ptr); printf("%d %d %d\n", arr[0], arr[1], arr[2]); free(arr); return 0; } Options: A) 100 20 30 B) 10 20 30 C) 100 20 120 D) Garbage value 💬 Kindly drop your answer in the comments along with your reasoning. ⚠️ Small hint: --> realloc may change memory location --> (*p)[2] depends on old values --> Order of updates matters --> Double pointer allows modification of original pointer #CProgramming #EmbeddedSystems #FirmwareDevelopment #Pointers
To view or add a comment, sign in
-
⚙️ Built a complete compiler toolchain from scratch, targeting a one-instruction computer Inspired by my digital electronics class with Dr. Charbel Fares, I explored what happens when you strip computation down to its absolute minimum: SUBLEQ (“subtract and branch if ≤ 0”) From there, I implemented a full pipeline What I built: • A SUBLEQ virtual machine • A compiler toolchain that translates a subset of C into SUBLEQ programs • A basic runtime model to support control flow and memory layout • End-to-end execution from high-level C code → raw one-instruction execution GitHub: https://lnkd.in/dvYeh5Ts The interesting part was realizing how much of computers are really just structures layered on top of a very small set of primitives We tend to think that computers are intelligent systems until we go deep into low-level stuff and realize that they're just deterministic machines This project sits somewhere between digital design and compilers, and helped me explore both If you’re into compilers, low-level systems, or minimal architectures, SUBLEQ is one of those rabbit holes that would be interesting to you :p
To view or add a comment, sign in
-
C++26 will introduce 𝗿𝗲𝗳𝗹𝗲𝗰𝘁𝗶𝗼𝗻 and we are all very excited about it. But there currently exist many 𝗹𝗶𝗯𝗿𝗮𝗿𝗶𝗲𝘀 that offer reflection for C++, how is that possible? Most of them use the __𝗣𝗥𝗘𝗧𝗧𝗬_𝗙𝗨𝗡𝗖𝗧𝗜𝗢𝗡__ compiler trick. This trick has been around for quite a while in modern compilers like GCC, Clang and MSVC and it’s very useful for this situation. It basically prints a string with 𝗳𝘂𝗻𝗰𝘁𝗶𝗼𝗻 𝘀𝗶𝗴𝗻𝗮𝘁𝘂𝗿𝗲 information at compile time. With some 𝘁𝗲𝗺𝗽𝗹𝗮𝘁𝗲 𝗺𝗲𝘁𝗮𝗽𝗿𝗼𝗴𝗿𝗮𝗮𝗺𝗶𝗻𝗴 techniques (like really heavy machinery) it is actually possible to achieve a functional reflection for pre-C++26 standards. It’s limited, but kind of works for lot of situations. The trick itself is 𝗻𝗼𝘁 𝗳𝘂𝗹𝗹𝘆 𝗽𝗼𝗿𝘁𝗮𝗯𝗹𝗲 and must be used carefully, as every compiler produces different output formats. Luckily, some developers have already squeezed this into heavily templated, ready-to-use libraries that do all the hard work for you. C++26 reflection will likely replace these approaches with a 𝘀𝘁𝗮𝗻𝗱𝗮𝗿𝗱𝗶𝘇𝗲𝗱 𝘀𝗼𝗹𝘂𝘁𝗶𝗼𝗻. Until then, this is what “reflection” in modern C++ looks like in practice. reflect-cpp: https://lnkd.in/ejaVevUa magic enum: https://lnkd.in/eK4tPPPe #cpp #c #cplusplus #modernc #moderncpp #cpp17 #cpp20 #cpp23 #cpp26 #coding #code #programming #reflection #array #pointer #arithmetic #typesafety #tech #future #embedded #software #firmware #cleancode #distributed #systems #compiler #gcc #clang #msvc
To view or add a comment, sign in
-
-
The bug? A single volatile keyword missing on a shared register read. Cost: 3 weeks of team productivity Impact: 15% throughput improvement when fixed Lesson: Always, ALWAYS mark hardware registers as volatile Here's what I learned: 1. Volatile isn't optional for hardware reads 2. Compiler optimizations will betray you 3. "It should work" is the most dangerous phrase in firmware 4. The simplest bugs hide in plain sight 5. Write unit tests for your hardware abstractions To everyone debugging a "impossible" bug today: It's not impossible. It's just hiding. Keep digging. The answer is there. Drop your worst "shouldn't happen" bug below. 👇 #Firmware #C #Debugging #Embedded #NVMe #Python
To view or add a comment, sign in
-
💥 Stop the NullReferenceException — C# Nullable Reference Types NullReferenceException is the #1 runtime crash in C#. And 99% of the time — it's completely preventable. Here's how to eliminate it 💥 The Problem string name = GetName(); // could be null int len = name.Length; // 💥 CRASH at runtime You won't know it's null until production blows up. ✅ Enable Nullable in C# 8+ Add this to your .csproj: <Nullable>enable</Nullable> Now the compiler warns you before the crash happens. Bugs caught at compile time, not runtime. ❓ string? vs string string name = "Ahmad"; // guaranteed non-null ✅ string? name = null; // explicitly says "this can be null" 🛡️ Null-Safe Operators — Use These Daily user?.Name // null if user is null — no crash name ?? "Anonymous" // fallback if null name ??= "Default" // assign only if null ⚠️ Null Forgiving Operator — Handle with Care string name = GetName()!; // tells compiler "trust me" Use this ONLY when you are 100% certain the value is not null. Otherwise you're just hiding the problem. 💡 Enabling nullable annotations is one of the easiest wins in any C# codebase. It takes 5 minutes to enable and saves hours of debugging. Have you enabled nullable in your projects? #CSharp #DotNet #BackendDevelopment #SoftwareEngineering #CleanCode #Programming #ASPNET
To view or add a comment, sign in
-
-
I came across std::array in some C++ code recently and had an honest realization — I almost never reach for it in my day-to-day work. For simple use-cases, raw C-style arrays still feel more direct. No wrappers, no abstractions — just a fixed block of memory that does exactly what you expect. But when things get even slightly complex, my instinct immediately shifts to std::vector. Dynamic sizing, cleaner memory management, and overall flexibility make it hard to ignore. So where does std::array really fit? It is safer than C arrays — no decay to pointers, better integration with STL algorithms, and compile-time size guarantees. But in practice, it often sits in this awkward middle ground: * Too “structured” for trivial use * Too limited for dynamic scenarios That said, I’ve started noticing a few areas where it actually makes sense: * Fixed-size buffers where size is known at compile time * Performance-critical paths where heap allocation must be avoided * Interfacing with APIs that expect contiguous memory but still want type safety * Embedded or low-level systems where predictability matters I’m curious — do you actively use std::array, or does it also fall into that “I know it, but rarely use it” category for you? #cpp #cplusplus #softwareengineering #systemprogramming #embeddedsystems #stl #coding #developers #programming
To view or add a comment, sign in
-
-
🚀 Rotate Array(Left Rotation) Problem 🧩 Problem: Rotate an array to the left by d steps 👉 Constraint: Do it efficiently ❌ Common Mistake: Using brute force rotation (shifting elements one by one) 👉 Time Complexity = O(n × d) 👉 Result = TLE (Time Limit Exceeded) 🚫 ✅ What I Did Instead: ✔ Reduced unnecessary rotations → d = d % n ✔ Used index mapping logic ✔ Placed elements directly in correct positions 📊 My Solution: ⏱ Time: O(n) 📦 Space: O(n) 🧠 What I Learned Today: ✔ Brute force ≠ bad, but not always acceptable ✔ Constraints decide your approach ✔ Optimization is what separates beginners from engineers #dsa #leetcode #arrays #java #algorithms #coding #programming #softwareengineering #developers #problemSolving #tech #interviewprep #100daysofcode
To view or add a comment, sign in
-
Explore content categories
- Career
- Productivity
- Finance
- Soft Skills & Emotional Intelligence
- Project Management
- Education
- Technology
- Leadership
- Ecommerce
- User Experience
- Recruitment & HR
- Customer Experience
- Real Estate
- Marketing
- Sales
- Retail & Merchandising
- Science
- Supply Chain Management
- Future Of Work
- Consulting
- Writing
- Economics
- Artificial Intelligence
- Employee Experience
- Workplace Trends
- Fundraising
- Networking
- Corporate Social Responsibility
- Negotiation
- Communication
- Engineering
- Hospitality & Tourism
- Business Strategy
- Change Management
- Organizational Culture
- Design
- Innovation
- Event Planning
- Training & Development
Thank you for post, as you’ve stated virtual come with memory overhead. So any suggestions on how to implement inheritance while avoiding virtual?