I have a memory like a colander - we have indeed had this conversation before, sorry!
I assumed it had something to do with the unity build. I also do it for my code, but I include the relevant headers in each cpp, so VS doesn’t complain. Thing is, this stopped working for JUCE some weeks ago, so something has changed. Just to clarify, this case would be something like
// source1.cpp
// header.h not included here
// source2.cpp
// header.h not included here either
// unity_source.cpp
#include header.h
#include source1.cpp
#include source2.cpp
Edit: I see this was already happening in VS Code. It’s happening in plain VS now
How does this work with multiple modules? I can see it not being a problem for a single module acting as a single unity build - but most of the JUCE modules rely on things from other modules which is the thing that makes me caucious about adding too many includes to the individual source files… how do you ensure that each module is only parsed and compiled once?
It works the exact same way. Nothing changes in the build system. You have include guards which prevent cases of the same header including multiple times in the same module/TU.
It really isn’t be any different than other C++ code with the only exception being that there’s one cpp file that includes others instead of many different files passed to the compiler.
The JUCE module system isn’t changing how the headers are included by other modules or by your plugin/app.
BTW - the point isn’t to add many includes, it’s just to do them from the source files themselves, like your regular code.
For example:
// MyModule/HelperFuncs.h:
#pragma once
#include <juce_core/juce_core.h>
void func(const juce::String& text);
// MyModule/HighLevelFuncs.h
#pragma once
#include "HelperFuncs.h"
//No need to re-include juce_core here, as it's already included
void someOtherFunc(const String& text) { func(text); }
Now, you can add the MyModule.h
public header that includes HighLevelFuncs.h
and you’re done.
Then, include that in user code/other modules. You can also just include any of the internal headers directly to save some compilation time, and of course also include them in the cpp files where they’re needed.
The include guards will protect you from multi-include, and parsing will work even on the most primitive text editor, because the editor will be able to recursively check all the included headers, which it can’t now without poking at the build system internals.
So would the JUCE source files only include the module header? I had assumed you meant that each source file would include the specific files they relied on, e.g. Component.h
would include String.h
, Rectangle.h
, Point.h
, Graphics.h
, etc.
Yes.
Ideally, modules define a library with one public header (just like they do now).
Currently includes of that external header (and includes to other headers in the same module) are defined in the public header of modules that use them. I suggest the same include will be moved inside the specific header that uses it, just like how it probably already works with most non-module code in the world.
I just checked Visual Studio Preview 17.5 and it’s not fixed. Apparently we cannot rely on Microsoft on this topic. I would strongly recommend to add includes to the cpp files.
It looks like its is sufficient to add the module header to each cpp file.
If you haven’t — please report this problem to microsoft, so they can reevaluate the importance of this bug, cause its a real productivity killer.
Here is a simple way to reconstruct the problem which you can use in your error report:
- clone
https://github.com/juce-framework/JUCE.git
- Open
extras/Projucer/Builds/VisualStudio2022/Projucer.sln
- Navigate to
juce_Component.cpp
→ Intellisense finds error like “Component is not a type”, and underlines the wrong findings, what distracts from the real mistakes.
I develop mainly in Windows and I have never seen this problem with my setup. I am using the latest VS 17.4.4
Not in my projects, neither in the Projucer example you suggest as test case. I can click on and follow identifiers, no wrong underlinings, etc.
I do not use CMake, I am still using Projucer for saving the VS solutions/Xcode projects, also in CI.
I do use tools JetBrains Resharper tools in VS, maybe this could overrule the Intellisense issues you mention?
Just to let you know.
Interesting, should probably give Resharper a try, now that it seems that it improved a lot with C++.
Visual Assist doesn’t work properly.
Thanks for the info. (Maybe Resharper just deactivates the internal intellisense)
The issue has been confirmed by microsoft employees. But I’m not sure if it’s prioritized high enough, so that they actually will fix it.
So I encourage you to report this issue too. “Unity Builds” are maybe not so common, that microsoft doesn’t think this has a broad impact on users.
Is there a post on Visual Studio Feedback forum that has already been submitted that we can go and upvote so that they do raise it on their priority list?
Can someone who reported this to microsoft provide a ticket number or a link so we can chase it as well? Would be good to get this fixed.
Here is my report about this issue, I tried to create a better one, but it seems they don’t like duplicates so we have to live with this one. It would be great if you upvoted it and also engaged in the thread so microsoft realizes it’s important.
https://developercommunity.visualstudio.com/t/Intellisense-Errors-in-CPP-File-underli/10114557
Thanks. I’ve upvoted it and added a comment to hopefully get it up the priority list.
New VS22 preview has a fix implemented, and it’s fixed the issue on my system.
That’s amazing Thanks for sharing. Just need to hope they apply the same to VSCode soon?
VS Code and VS share no code, as far as I know. VS Code’s ‘intellisense’ usually comes from external plugins, even though there’s one popular one made by Microsoft.
Also, the VS Code extensions are not aware of the build system, while the VS intellisense is connected to the entire compiler toolchain.
In theory, VS Code extension like ClangD or the Microsoft C++ extension could implement a parser that is aware of the entire build system, but it doesn’t look like they’re making an effort in this direction.
That’s a shame, thanks for sharing.