Site icon Tomato Soup

AI Coding Assistants for Large C++ Codebases: What Works, What Breaks, and How to Split the Work

AI Coding Assistants for Large C++ Codebases: What Works, What Breaks, and How to Split the Work

AI tools are everywhere. They’re in your phone, your car, your office, and it even made its way into software development. It’s being pushed as a do-it-all solution for coding, and in many cases it does solve, or the very least,  speeds up the busywork. The benefit is real and it’s useful. But today we try to locate the threshold of where that convenience should end. It’s the conversation around speed vs accuracy in a field were exactness is a necessity.

Take for example, if you work on a project measured in millions of lines, you have probably run this experiment yourself. Maybe your manager asked why the team isn’t “using AI yet,” or maybe you did. Either way, the results were confusing. The same tool that built a test harness in forty seconds also invented a function that has never existed in twenty years of commit history. The assistant wasn’t lazy. It was confident, and in a big C++ codebase, confidence without proof gets expensive.

Both things really happen, and both have clear causes. This post covers what AI assistants do well in big codebases, why they get worse as projects get bigger, why C++ makes that worse still, and a simple way to split the work so you keep the good part without paying for the bad part.

TL;DR: AI coding assistants do useful work in large C++ codebases: rough drafts, explanations of unfamiliar code, boilerplate, and tests. But they get less reliable as the codebase grows. No tool can fit millions of lines into the limited amount of text a model can read at once, answers get worse as a session drags on (“context rot”), and AI makes predictions even when a codebase question needs an exact answer. C++ makes all three problems sharper, because the code a model reads is not the code the compiler builds. In a controlled study by METR, experienced developers were 19% slower with AI on large, mature codebases. CodeRabbit reviewed 470 pull requests and found AI-assisted ones had about 1.7x more problems. A bigger context window is a bandaid solution. Split the work between exact tools for navigation, references, and renames; and AI for drafts and explanations, with a human reviewing the output.

What AI assistants are actually good at

Let’s start with what works, because the many doomer posts may unintentionally plant the idea of a hopeless scenario with no recourse.

AI assistants shine at tasks where getting a decent first draft is valuable and you intended to review the output anyway. That covers prototyping an idea before you commit to it, setting up a proper test framework, or writing the four-hundredth serialization function of your career. It also points you in the right direction when you encounter an unfamiliar corner of the codebase. It feels like real sorcery next to traditional code reading: you can almost hear the whispers of the original author who left in 2019 (or at least a semblance of them).

That last one deserves emphasis. When you are new to a big, old codebase, asking “what is this class trying to do?” is often faster than an hour of digging, even when the answer is only 85% right. You are using the model as a reading aid, and a reading aid doesn’t have to be perfect. It only has to be fast and mostly right.

If an assistant has been useful to you for these tasks, that matches the research, and it’s hard to blame anyone for wanting more of it. The trouble starts when 99% accuracy is the requirement, performance is essential, there is no leeway for guesswork, and you look for all of that in your AI-powered tool.

What breaks as the codebase grows

The AI only sees a slice of your code

Every AI model has a limit on how much text it can consider at once. That limit is called the context window, and a large Visual Studio solution will never fit inside one. So the assistant’s tooling picks a slice for it: your open files, some search results, a summary of the repo. That slice decides the answer. If the slice misses the one header where a behavior is actually set up, the model doesn’t say “I can’t see that file.” It answers anyway, and it sounds right, using only what it has. Martin Fowler’s site has a good piece on this: managing what the model sees is the whole game, and on a big repo that game is hard.

Context rot

There’s a second, sneakier failure. Context rot means the model’s answers get worse as its window fills up, even before it hits the official limit. Chroma’s research tested 18 models and found their performance gets unreliable as the input grows, even on tasks they handle easily when the input is short. Coding sessions make it worse. Old messages, failed attempts, and debug output pile up and act as noise, and the assistant that had sharp answers at 10 a.m. is confidently wrong by 11:30. Developers have worked out folk remedies, and the most common one you’ll see in community threads is simple: stop the session and start fresh.

The hidden cost: reviewing the output

All of this accrues debt that needs to be paid off during review time. In mid-2025, METR ran a controlled study with experienced open-source developers working in big, mature projects they knew well. With AI help, they took 19% longer to finish their tasks. Those same developers believed the AI had made them about 20% faster. The time spent prompting, checking, and fixing didn’t feel like a cost while it was happening.

The quality data says the same thing. CodeRabbit reviewed 470 open-source pull requests and found the AI-assisted ones had about 1.7x more issues than the human-only ones. Logic errors were up 75%, and one class of performance problem showed up at nearly 8x the rate. Neither study is C++-specific, so treat the exact numbers as rough guides. But the pattern they describe, review work that grows with the size and complexity of the code, is exactly what a large C++ project has the most of.

Why C++ makes it worse

Every language runs into the context-window problem. C++ pays extra, because in C++ the code you write and the program the compiler builds are further apart than in almost any other mainstream language.

Here’s the gap. An AI model reads your source code as text. But before the compiler builds that text, a step called the preprocessor rewrites it: macros get expanded, #include lines pull in whole files, and conditional blocks get kept or dropped. Templates add another rewrite at build time. The result of all this for one .cpp file is called a translation unit, and it can run to hundreds of thousands of lines even when the file you wrote is short. The interesting behavior often lives in that rewritten version, which the model never sees. A function that appears “called nowhere” in your source can be called everywhere in the build, thanks to a macro that pastes names together. Ecosystems built on heavy macros (Unreal Engine is the famous example) widen the gap even more.

Put simply: the model reads the document you wrote, while the compiler builds a different document that your tools generate from it. When the two disagree, the LLM assistant sides with the one it can see. That’s how a rename ships with thirty-one call sites fixed and eleven missed, and it’s why the failures feel random when they aren’t. They track exactly with how much of your program’s meaning lives on the far side of the preprocessor.

Split the work

So what’s the move? Most vendor guides in this space conclude that you need an assistant with a bigger index of your code. More retrieval does help a little. But it doesn’t change the two facts underneath: AI output is a prediction, and some questions about your codebase should never be answered with a prediction.

A more durable rule is to sort tasks by the kind of answer they need.

Demand exactness for questions with one right answer. Where is this defined? Who calls this? What breaks if I rename it? These are lookups against the real structure of your code, and the tool answering them should be an algorithm, not a model. An algorithm that parses your code gives the same answer every run on the same code. There is nothing to hallucinate. Either it indexed the symbol or it didn’t, and you find out immediately.

Hand the AI the tasks that benefit from a generated draft: first passes, explanations, test scaffolds, mechanical changes you’ll review line by line. Here a prediction is fine, because you never planned to trust it blindly.

Control what the model sees, and let a human make the final call on every change. A selected block or a single file is an input you can reason about. An always-on agent that reads the whole repo in the background gives you a slice you can’t inspect, feeding answers you can’t trace.

Task in a large C++ codebase Demand exactness Fine for AI
Find all references to a symbol ?
Rename across the project ?
Navigate to a definition or implementation ?
Explain what this function does ?
Scaffold a unit test ?
Prototype an approach before committing ?

The teams that report AI working for them at scale are, in practice, running some version of this split, whether or not they’ve written it down.

Where Visual Assist sits in this

If your workflow needs the exact half, this is what we build. Visual Assist runs its own C++ parser inside Visual Studio. It parses in parallel and re-parses incrementally, and it’s designed to understand code rather than compile it. Because it never needs to build your code, it keeps resolving symbols and references even through code that won’t compile, which is most code during most of the working day. Find References, rename, and navigation are checked answers from a parser, so the same code gives the same result every run. It’s the property the 2 a.m. rename at the top of this post was missing.

For the AI half, VA Intelligence currently ships two lightweight try-it-first features: Explain with AI and Change Code with AI. Both work only on the code you select, so you decide exactly what the model sees. Both run locally on your own hardware, so that boundary comes from how the tool is built rather than from a policy document. Nothing runs until you invoke it (Shift+Alt+Q), and nothing is applied until you approve it. More context-aware features are coming, and they’ll follow the same posture. If you already run Copilot, the two coexist.

Evaluate in a day, not a 90-day roadmap

Enterprise vendor guides propose phased rollouts with steering committees. You can learn most of what matters on your own solution before lunch, with three tests:

  1. Test it on truth. Open your ugliest file and ask the assistant who calls a macro-wrapped function. Then ask it to rename something with 50+ references, on a branch. Check both answers against an exact Find References and a parser-driven rename, and count the misses.
  2. Time it honestly. Time one real task end to end, including the review and fixes. The METR result says your gut will flatter the tool, so measure instead.
  3. Watch what it costs your IDE. AI features add background work, and “why is my Visual Studio so slow” threads have become a genre of their own, with reports of slowdowns while Copilot runs on Microsoft’s own feedback forum. Watch typing lag and memory while the assistant is active, confirm it plays nicely with the tools you already rely on daily, and check what leaves your machine if confidentiality matters in your shop. A tool that drags the whole IDE taxes every hour you work, not just the AI-assisted ones.

If the assistant aces tests 2 and 3 but fails test 1, then you can assume that it’s a tool being misused for the inappropriate task. Splitting responsibilities and use cases is the easy fix.

FAQ

Do AI coding assistants work on large C++ codebases? Yes, for tasks shaped like “generate a draft”: prototypes, explanations, boilerplate, tests. They get unreliable on tasks shaped like “tell me the truth about this code,” such as project-wide references and renames. Use exact code-intelligence tools for the second kind and the assistant for the first.

Why do AI assistants struggle with C++ specifically? The preprocessor. An AI reads your source text, but the compiler builds a rewritten version of it, with macros expanded, headers pulled in, and templates filled out. In large C++ projects, much of the program’s real meaning lives in that rewritten version, and the model never sees it.

What is context rot? Context rot is the drop in answer quality as a model’s input fills up, even before it reaches the official limit. Chroma’s research documented it across 18 models. In long coding sessions, old history and failed attempts pile up as noise, which is why quality often slides as a session ages.

Will an AI assistant conflict with Visual Assist? No. Visual Assist and Copilot Chat have worked side by side since build 2024.2, and VA Intelligence is designed to complement outside assistants, not replace them. Among developers who rely on VA daily, an AI tool that breaks it tends to be the one that gets uninstalled.

Keep the AI. Give it a partner that knows.

One thing is easy to forget in 2026, with every tools company pitching a model: the exact half of this split is not new. Deterministic code tools (parsers, indexers, symbol databases) have been answering the truth-shaped questions for decades, and there’s a decent chance one is already sitting in your Visual Studio setup, half-remembered. They didn’t stop working when the chatbots arrived; they just stopped getting the headlines. Through every failure in this post, the assistant’s confidence never wavered, and that’s the thing to design around. Confidence should be earned by checking, and the tools that check came first. So let a parser be confident about what your code is, let the model be useful about what your code could be, and stop paying a review tax on questions that never needed a guess.

If you’re evaluating AI tooling for a C++ team and want to compare notes, drop us a line; how AI behaves on real-world C++ is something we actively collect field reports on.

 

Exit mobile version