0

When I use the BOOST_FOREACH macro in a C++ method, the implementation is no longer detected automatically since the method is forced out of the respective namespace as determined by Visual Studio (perhaps Intellisense?). There are no problems with compilation. What is going on here?

.h

class testClass
{
public:
    testClass();
    ~testClass();

    void print();
};

.cpp

#include "testClass.h"
#include "stdafx.h"
#include <boost/foreach.hpp> // BOOST_FOREACH
#include <iostream> //std::cout, endl

testClass::testClass()
{
}

testClass::~testClass()
{
}

void testClass::print()
{
    int nums[] = { 1, 2, 3, 4, 5 };
    BOOST_FOREACH(const int a, nums)
    {
        std::cout << a << std::endl;
    }
}
  • 2
    What do you mean "the implementation is no longer detected automatically"? What exactly is the problem that you are experiencing? – Lightness Races in Orbit Nov 06 '18 at 11:01
  • 2
    BTW, which VS are you using? Since VS2012, you should be able to use C++ range-based for instead of `BOOST_FOREACH`. – Angew is no longer proud of SO Nov 06 '18 at 11:02
  • I think you assume things about the intellisense engine that make little sense. This has little to do with "namespaces" (likely: nothing). Instead, it's the case of Intellisense not properly grokking the preprocessed source.This can happen for many reasons. In fact it very often happens that code compiles fine if intellisense is lost. – sehe Nov 06 '18 at 11:08
  • A search like this one https://stackoverflow.com/search?page=2&tab=Relevance&q=c%2b%2b%20intellisense will demonstrate that inconsistent hebaviour from Intellisense is pretty common, and in principle not really solvable (beyond: you can try with a newer version of Visual Studio) – sehe Nov 06 '18 at 11:13
  • @LightnessRacesinOrbit Although the method's implementation is in the .cpp, VS can't detect it and the method doesn't appear in the drop down list – Matthew Green Nov 07 '18 at 08:54
  • @Angew I'm in VS2015 but the libraries I'm using force me to use the v100 toolchain which doesn't support range-based for :( the problem exists both in VS2010 and 2015 – Matthew Green Nov 07 '18 at 08:58
  • @sehe My question is why the boost macro causes this behaviour, that is the failure to detect the method's implementation in the .cpp – Matthew Green Nov 07 '18 at 08:58
  • And the answer to that is: because macros are a preprocessor feature and often make all kinds of tools go off the rails when trying to parse code. In effect, it can only work if the tools do the complete preprocessing, and what's worse: with the same compiler flags to get the same result as during compilation. – sehe Nov 07 '18 at 09:07
  • In a way the answer to "What's happening" is: "C++ is happening". But I expanded on that a bit in an answer. – sehe Nov 07 '18 at 09:32

1 Answers1

0

@sehe My question is why the boost macro causes this behaviour, that is the failure to detect the method's implementation in the .cpp – Matthew Green 10 mins ago

The answer to that is: because macros are a preprocessor feature. Fully implementing the preprocessing is an expensive thing to do both in implementation complexity and in runtime cost. Many tools simplify/take shortcuts when trying to parse C++ code.

Accurate results can only be achieved if the tools do the complete preprocessing, and parsing in the exact same way that a compiler does¹. If you know a bit about the complexity of compilers then it should not come as a surprise that very few tools do this.

The most notable exception to the rule is libclang which does allow vendors to create "high-fidelity" C++ tools without having to implement all the mechanics.

For this reason, I use YouCompleteMe with CMake's compiler_commands.json to make sure that libclang always uses the same flags and defines. It yields the best completions and diagnostics I've seen among IDE's and tools.

That said, I have no problems using the lesser tools (Eclipse's C++ indexing, Microsoft's Visual Studio Intellisense, QtCreator's completion²). It's just something that historically comes with the field of C++, that tools may not always be able to grok every construct.


¹ And it must be using the same include paths, flags and defines

² Other notable mentions are Doxygen and ... SourceInsight (which I never used, but analyzed here: How can I make SourceInsight understand smart pointers?)

sehe
  • 374,641
  • 47
  • 450
  • 633