Eclipse cannot resolve fields declared with macro - c++

I've recently started diving into the code of an open source project, which is largely written in C++. I'm using Eclipse 3.8 in Ubuntu 12.10.
THE PROBLEM:
Eclipses is incorrectly flagging fields as unresolved because of a particularly elaborate convention used to separate field declarations out of the header files.
someclass.h
class SomeClass
{
public:
#define MACRO_CLASS_PARAM(Name) SomeType m_##Name;
#include "fields.h"
#undef MACRO_CLASS_PARAM
};
fields.h
MACRO_CLASS_PARAM(Field1)
MACRO_CLASS_PARAM(Field2)
...
Now in the cpp file, if I want to do something like instanceOfSomeClass.Field1 Eclipse will flag it as an error with "Field 'Field1' could not be resolved".
THE QUESTION: Is there any way to get Eclipse to correctly handle this situation?

The inability to correctly process #include statements that are not at global scope is a long-standing deficiency in Eclipse's indexer.
Things you could do about it:
Revise your code to avoid this pattern. Once the textual header inclusion model is superseded by C++ Modules, it's going to be invalid anyways.
Contribute a fix for this deficiency to Eclipse CDT.
Use a different IDE that can parse this pattern. (I don't know of one off the top of my head, but I also haven't spent a lot of time looking.)

Related

Visual Studio Intellisense + Resharper throws ambigous symbol error when including the same header twice

I am using Resharper C++ with visual studio and I am getting an ambigous symbol error due to an apparent namespace clash. I get this error in Sd.cpp when, for example, I want to instantiate an enum Mode.
The enum class Mode is defined in Pins.hpp, which is included in Sd.hpp. However if I include Pins.hpp in Sd.ccp the ambigous symbol error pop ups. There is no problem compiling the project.
Could Resharper / Intellisense be not recognizing that Pins.hpp is the same file? The way #pragma once works is by the file path, so I don't know how that would happen.
I recently changed the include directories, so maybe this has something to do with the issue.
Any help would be appreciated.
Sd.hpp
#include "Pins.hpp"
Sd.cpp
#include "Pins.hpp"
Mode mode; //error here, Mode is underlined
Pins.hpp
enum class Mode : uint32_t
{
AlternatePushPull = GPIO_MODE_AF_PP,
};
EDIT1: Added code.
EDIT2: Renamed question to something more usefull
Turns out ReSharper looks into the entire VS solution when linting, not solely the project. Since in my solution I had some project which included the same libraries, but from a different location. Therefore ReSharper could not resolve the names.
The solution was simple: make sure that all projects all include the same files.

C++ namespace "hiding" appearing in the Eclipse parser

Recently I have being working on a project using C++ as the programming language and Eclipse CDT as the programming IDE. The 'Chrono' library is used in the project.
I was trying to define the "<<" stream operator for different time scales like nanoseconds by putting the definitions in the same namespace as chrono, namely "std::chrono". One small example of the code of the header file (Test.hpp) is illustrated as following:
#include <chrono>
#include <iostream>
namespace test{ namespace chrono{
typedef std::chrono::nanoseconds nanoseconds;
}}
namespace std{ namespace chrono{
inline std::ostream& operator<<(std::ostream& s, nanoseconds dur)
{
return s << dur.count() << "ns";
}
}}
The above code together with other parts of the project can be compiled correctly. However, the IDE, Eclipse CDT, keeps complaining "Type 'std::chrono::nanoseconds' could not be resolved" and the auto-completion functionality says "No Default Proposals" for any member variables/functions in the namespace "std::chrono". It looks like that adding new functions into the "std::chrono" namespace in this header file somehow 'hides' other content from the Eclipse's point of views.
The question is what could be the reason leading to such 'error' messages in Eclipse CDT or it is one flaw in my programming? I would appreciate any help or hint from you.
I also copy-past the code into Xcode on the laptop and there is no such error message as in Eclipse CDT.
Additional information:
The os I am using is Mac OS, thus the chrono library is slightly different from that mentioned in the answer. The screenshot of 'chrono.hpp' is as following:
Actually, my CDT has no issue to find the members in the namespace 'std::chrono::'. What confuses me is CDT's behaviour when I add/override members in the namespace 'std::chrono::'. See the following pictures:
Errors appear when I override a member function in the namespace:
Errors do not appear when I do nothing on the namespace:
Any idea on how to solve this problem?
Assumptions about your setup
I believe you have changed your build settings to use -std=c++0x or something similar as the chrono library requires it.
Perhaps you did it like this:
At the top of chrono (header file) there is a bit like this:
#if __cplusplus < 201103L
# include <bits/c++0x_warning.h>
#else
so that if you don't have sufficiently new C++ standard, you get a compile error.
Now the problem is the CDT indexer that is used to generate highlighting and code completions does not know you are using __cplusplus >= 201103L. You can see this in this following screenshot that the majority of chrono is inactive because __cplusplus is the wrong value.
This screenshot shows the incorrect value and the errors CDT identifies:
And if you try and code complete, you get the wrong thing too:
How to fix it
To fix the problem, you need to tell CDT that your project uses GCC settings that are different from the default GCC settings. i.e. because of the different standard __cplusplus in particular has the wrong value.
In Project Properties, choose C/C++ General -> Preprocessor Includes and then the Providers tab.
Choose the CDT GCC Built-in Compiler Settings
Uncheck the Use global provider shared between projects
Press OK
Here is a screenshot of what that looks like:
Once you do this, you should see that chrono's inactive sections becomes correct in the editor:
But your source file may still be wrong. You should then rebuild the indexes to update, right-click on the project, choose Index -> Rebuild:
Finally your code should not display properly:
And the code complete should be working too!
History
This is a case where CDT's right hand and left hand don't agree. Historically I believe the reasoning for this is down to performance and trading off indexing every possible variant of compiler/user option, vs having some shared data across the workspace that may be wrong for some projects.

How to make sure code (c++) written in Xcode can compile on other platforms?

I am a beginner was trying to do some C++ programming on Xcode. It works fine, but when I try to compile the same c++ file on my windows pc using VS, there were some errors. After I look at my code closely, there are really some stupid mistakes that I have made which caused the errors, but Xcode seemed to have ignored them...
My question is that is there any setting that I need to change to prevent Xcode from being so smart?
For example, the following code can actually compile in xcode:
#include <iostream>
using namespace std;
int main() {
if (true or false){
cout << "How is this possible? \n";
}
return 0;
}
There are also other cases where the code is actually wrong, but it can compile just fine is Xcode which is the annoying part and I want to disable that.
As far as I can see there is nothing wrong with your code.
The ISO C++ standard does not specify which standard headers are included by other standard headers. So, it is entirely possible that the version of iostream used by Xcode directly or indirectly includes ciso646. Whereas Visual Studio's version of iostream does not include ciso646. There are many similar cases with other headers. You just need to read the error messages and realize that your error (when you move your file to a different platform) is due to a missing header file.
It would be nice if writing portable code meant writing code in accordance with the C++ standard specification, but unfortunately that's not the case. Although there are various compiler options on various implementations which can help bring different implementations closer together, in general you will just have to bring the code into the target environment and actually test it there.
So ultimately writing portable code means you'll have to learn some subset of C++ that is accepted by all the implementations you want to target.
or is an 'alternative token' in C++, and VS is incorrect to reject it. There's no option in Xcode to disable support for alternative tokens. However VS has non-standard support for or as a macro using the header <ciso646>, and Xcode does have a header <ciso646> which does nothing (as the standard specifies). So you can write code which uses or and which works in both Xcode and VS by including this header.
#include <iostream>
#include <ciso646> // does nothing in Xcode, allows `or` in VS
using namespace std;
int main() {
if (true or false){
cout << "How is this possible? \n";
}
return 0;
}
Unfortunately VS can't support all of the alternative tokens through macros and so Xcode will still support some that VS doesn't.
There are also other cases where the code is actually wrong, but it can compile just fine is Xcode which is the annoying part and I want to disable that.
If you give specific examples then I can provide additional advice on how to write portable code.
Rather than changing your Xcode settings, I suggest cross-checking your code using another development environment.
If you're looking for something cheap and full-proof. Download a VirtualBox Windows VM, and run download Dev C++ (bloodhshed)
VS does not support or: you need to use || instead.
You can include some special files but it doesn't inject or sufficiently well into the language for it to work in all instances.
If you want to suppress use of or (and your compiler supports no better way)
#define it to something that emits a compiler error, for example
#define or OR
This at least means that the nature of the compilation errors will be identical on Xcode and VC.

Strings in C++ class file for Arduino not compiling

I'm writing a stack class in C++ for an Arduino sketch. I believe it is fully compliant with the AVR (if that's what it's called; I can't remember exactly) compiler; I've used all malloc and free instead of new and delete and so on.
So I have a .h file with my class. I've imported it into the sketch, but when I try to compile, I get these errors:
In file included from sketch_may15a.cpp:1:
/CStack.h:58:18: error: string: No such file or directory
In file included from sketch_may15a.cpp:1:
CStack.h:61: error: variable or field 'Error' declared void
CStack.h:61: error: 'string' was not declared in this scope
And here are the first few lines for my class:
#include <string>
using namespace std;
void Error(string message) {
So the Arduino compiler can't find <string>, and the next few problems seem to relate to it (not sure what variable or field Error declared void means, my error function is just for debugging purposes).
I know Arduino sketches support strings without need for an import, but I'm not sure how that works out with C/C++/.h files. I've tried googling it, but there isn't much documentation.
Arduino sketches don't support any of the C++ standard library as they are compiled using avr-libc which doesn't support it. However, Arduino does provide the String class which should do what you need.
If you are writing a library you'll also need to #include <Arduino.h> (or #include <Wiring.h> if you are using a pre-1.0 version of the Arduino IDE).
Using String class in microprocessors is advised against due to heap fragmentation and other problems
The new SafeString library (available from the library manager) solves all those problems and is completely safe and will never cause your sketch to reboot.
see the detailed tutorial at
https://www.forward.com.au/pfod/ArduinoProgramming/SafeString/index.html

Cuda with Boost

I am currently writing a CUDA application and want to use the boost::program_options library to get the required parameters and user input.
The trouble I am having is that NVCC cannot handle compiling the boost file any.hpp giving errors such as
1>C:\boost_1_47_0\boost/any.hpp(68): error C3857: 'boost::any': multiple template parameter lists are not allowed
I searched online and found it is because NVCC cannot handle the certain constructs used in the boost code but that NVCC should delegate compilation of host code to the C++ compiler. In my case I am using Visual Studio 2010 so host code should be passed to cl.
Since NVCC seemed to be getting confused I even wrote a simple wrapper around the boost stuff and stuck it in a separate .cpp (instead of .cu) file but I am still getting build errors. Weirdly the error is thrown upon compiling my main.cu instead of the wrapper.cpp but still is caused by boost even though main.cu doesn't include any boost code.
Does anybody know of a solution or even workaround for this problem?
Dan, I have written a CUDA code using boost::program_options in the past, and looked back to it to see how I dealt with your problem. There are certainly some quirks in the nvcc compile chain. I believe you can generally deal with this if you've decomposed your classes appropriately, and realize that often NVCC can't handle C++ code/headers, but your C++ compiler can handle the CUDA-related headers just fine.
I essentially have main.cpp which includes my program_options header, and the parsing stuff dictating what to do with the options. The program_options header then includes the CUDA-related headers/class prototypes. The important part (as I think you've seen) is to just not have the CUDA code and accompanying headers include that options header. Pass your objects to an options function and have that fill in relevant info. Something like an ugly version of a Strategy Pattern. Concatenated:
main.cpp:
#include "myprogramoptionsparser.hpp"
(...)
CudaObject* MyCudaObj = new CudaObject;
GetCommandLineOptions(argc,argv,MyCudaObj);
myprogramoptionsparser.hpp:
#include <boost/program_options.hpp>
#include "CudaObject.hpp"
void GetCommandLineOptions(int argc,char **argv,CudaObject* obj){
(do stuff to cuda object) }
CudaObject.hpp:
(do not include myprogramoptionsparser.hpp)
CudaObject.cu:
#include "CudaObject.hpp"
It can be a bit annoying, but the nvcc compiler seems to be getting better at handling more C++ code. This has worked fine for me in VC2008/2010, and linux/g++.
You have to split the code in two parts:
the kernel have to be compiled by nvcc
the program that invokes the kernel has to be compiled by g++.
Then link the two objects together and everything should be working.
nvcc is required only to compile the CUDA kernel code.
Thanks to #ronag's comment I realised I was still (indirectly) including boost/program_options.hpp indirectly in my header since I had some member variables in my wrapper class definition which needed it.
To get around this I moved these variables outside the class and thus could move them outside the class defintion and into the .cpp file. They are no longer member variables and now global inside wrapper.cpp
This seems to work but it is ugly and I have the feeling nvcc should handle this gracefully; if anybody else has a proper solution please still post it :)
Another option is to wrap cpp only code in
#ifndef __CUDACC__