I've recently updated to Eclipse Mars.2 (version 4.5.2) and switched my project to C++11 development (yeah, it's about time!).
I've managed to configure all my Makefiles to build correctly (ie. no obvious errors or warnings) but the Eclipse built-in indexer reports several false-positive semantic errors. Not all of them have to do with C++11 specific features.
I'm referring to already existing threads [1] and [2] which are older and haven't brought any real solution for me.
False-positives examples
std::next(..) not recognized - but I have no problems with std::begin() or std::end():
std::vector<int> v;
for (auto i = std::begin(v); i != std::end(v); i++)
{
std::next(i);
}
Invalid arguments '
Candidates are:
#0 next(#0, std::iterator_traits<#0>::difference_type)
Semantic Error
std::string::substr(..) not recognized:
std::string myString = "test";
myString.substr(0, 1);
Invalid arguments '
Candidates are:
std::basic_string,std::allocator> substr(?, ?)
Semantic Error
googletest's ASSERT_EQ macro is not not recognized (however, other assertions work!):
std::string expValue = "test";
std::string actValue = "test";
ASSERT_EQ(expValue, actValue);
Function 'Compare' could not be resolved
Semantic Error
I've tested various project settings and I came to the conclusion that it has something to do with the Eclipse project's "Paths and Symbols" settings as well with the "Preprocessor Include Paths, Macros, etc." settings. Especially the order of the Providers is highly sensitive for any changes.
The additional problem is that I have an older system with gcc 4.4.4 compiler (default in /usr/bin/gcc) and an additional gcc 4.8.2 installed in /opt/... which shall be actually used for compilation. This also means that I have two sets of header files but only one includes the C++11 features.
My current configuration is this (as seen in Project Settings -> C/C++ General -> Preprocessor Includes Paths -> Entries):
CDT User Settings Entries
system headers of gcc 4.8.2 (treated as built-in)
preprocessor macro __cplusplus = 201103L
CDT Managed Build Settings Entries
paths to custom includes and library paths
CDT GCC Build Output Parser
CDT GCC Built-in Compiler Settings
non-changeable system headers of gcc 4.4.4
local includes
I have tried other combinations as well but this one gives me lowest amount of false-positive errors.
The indexer has project specific settings enabled. I haven't found any switch so far that makes the errors go away.
Has anybody experienced such problems as well? Is it a configuration issue of my paths and symbols or is it a bug in the Eclipse indexer?
std::next(i); is incorrect. When you use
for (auto i : v)
{
std::next(i);
}
i becomes of the type *(v.begin()) which in your code is an int. std::next requires an iterator and that iterator must also provide a difference_type type.
The whole purpose of a ranged based for loop is to not have to worry about advancing through the container. If you wanted to print everything out of the vector you would just use
for (auto i : v)
{
std::cout << i << " ";
}
I know this doesn't solve your other error but it fixes the first one
I updated Eclipse CDT to version 8.8.1 and the false-positive compile errors don't show up anymore. So after all it was a software bug.
Related
I have written a program using C++11 features.
/* * test.cpp * * Created on: 05-Jul-2015 * Author: avirup */
#include<vector>
#include<iterator>
#include<iostream>
using namespace std;
int main() {
vector<int> v;
v.push_back(5);
v.push_back(7);
for(auto i=v.begin();i!=v.end();i++) {
cout<<*i<<endl;
}
for(auto i=v.cbegin();i!=v.cend();++i) {
cout<<*i<<endl;
}
}
The program is compiling correctly and showing results but the editor is showing but red lines below valid functions like cbegin() and cend() which are constant reference iterators. which is annoying. How to get rid of this?
Just for completeness since this has no answer and give an explanation.
To achieve compiling with C++ 11 (or another version) and Eclipse actually supporting it you need to do two things.
First the compiler flag needs to set so -std=c++11 or -std=c++0x is appended when calling g++ or whatever is used.
Open the properties for the properties for the project. Select it and right click ↦ Properties (or Alt+Enter for Windows users)
Go to C/C++ Build ↦ Settings, maybe select your preferred configuration, ↦ GCC C++ Compiler (or any other compiler you use) ↦ Dialect.
Select from the combo or write the flag to the Other dialect flags if not present in the combo (like -std=gnu++14 or -std=c++1z).
CDT will now call your compiler with -std=c++0x when compiling. Now to the part so CDT supports C++11 and does not show errors for missing types and such. My libstdc++ contains lines like
#if __cplusplus < 201103L
# include <bits/c++0x_warning.h>
#else // C++0x
that causes your errors and the actual type declarations/definitions are greyed out if you view them in the C/C++ editor. __cplusplus needs to be set correctly with #define __cplusplus 201103L so they will be parsed and indexed by CDT. This is also done via the project settings or can also be done for the whole workspace.
Go again to the project settings.
C/C++ General ↦ Preprocessor Include Paths, Macros etc., also maybe select your preferred configuration, ↦ tab Providers.
Select the entry for your compiler (for me it’s CDT GCC Built-in Compiler Settings MinGW.
Add -std=c++11 or -std=c++0x to the Command to get compiler specs textfield at any location.
Optional: Select Allocate console in the Console View and hit apply. You should now see something like #define __cplusplus 201103L in the console.
To set it for the whole workspace just check Use global provider shared between projects and click on Workspace Settings where an almost identical dialog opens.
I’m currently writing a plug-in that extends the new C/C++ project wizard where one can select the C++ version for the project that sets the compiler flag correctly and also the above setting for the indexer and some other stuff. But dunno if it will ever will be integrated into CDT or needs to be installed via plug-in. But it sure will be in https://www.cevelop.com in a few months.
When reading the std library implementation I could see lots of checks enabled by #if _LIBCPP_DEBUG_LEVEL >= 2 conditions. I tried to add _LIBCPP_DEBUG_LEVEL = 3 in xcode preprocessor options, but <iterator> doesn't compile anymore:
#if _LIBCPP_DEBUG_LEVEL >= 2
__get_db()->__insert_i(this); <----- the error is on this line
#endif
Is there something else I'm missing here to use a higher debug level for the standard library?
According to the libc++ documentation:
Debug mode is currently not functional. Defining _LIBCPP_DEBUG will result in fairly nasty compile errors.
So that is probably the source of that.
Baum mit Augen's answer that _LIBCPP_DEBUG_LEVEL >= 2 standard library code for lower level iterator debugging is basically unusable, appears to still be the case with the out-of-the-box Xcode 11.6. But if you're up for extra work or just want more specifics, read on...
Enabling _LIBCPP_DEBUG_LEVEL code is enabling LLVM's Debug Mode. According to that documentation, enabling this debug mode is done by defining the _LIBCPP_DEBUG to a value of 0 (that "enables most of libc++’s assertions") or 1 (that "enables 'iterator debugging' which provides additional assertions about the validity of iterators used by the program").
In XCode 11.6, I've found that adding _LIBCPP_DEBUG=0 to a project's Debug Preprocessor Macros setting, compiles and links and indeed adds additional checks - at least checking against out of range references to std::vector elements via its [] operator. Enabling the _LIBCPP_DEBUG_LEVEL >= 2 code is done by instead setting _LIBCPP_DEBUG=1. That alone however won't fully link as not all the necessary symbols are found. Specifically, the std::__1::__libcpp_db::__insert_c(void*, std::__1::__c_node* (*)(void*, void*, std::__1::__c_node*)) symbol is reported as undefined and maybe others as well. Presumably, XCode 11.6 did not ship with this built into the standard C++ library it provides. If anybody knows better or could corroborate this, I'd appreciate hearing from them.
With the following extra work, I've been able to enable libc++'s assertions plus the additional iterator debugging capabilities:
Install a recent LLVM package somewhere that doesn't interfere with Xcode's included LLVM package. I installed LLVM 10.0.1 using Homebrew and I was able to access it then under /usr/local/Cellar/llvm/10.0.1.
Have Xcode recognize the Xcode tool chain support that this new LLVM package provides. I added a symbolic link to /usr/local/Cellar/llvm/10.0.1/Toolchains/LLVM10.0.1.xctoolchain into Xcode's /Applications/Xcode.app/Contents/Developer/Toolchains directory. I'd done that while Xcode was running and it immediately saw the new tool chain but I had to restart Xcode to get it to compile with it.
Under Xcode's "Xcode" -> "Toolchains" submenu, select the new tool chain. My setup showed "Xcode 11.7" and "org.llvm.10.0.1" and I selected the latter to accomplish this.
Add the path to the new tool chain's usr/lib directory to the LIBRARY_SEARCH_PATHS declaration for resulting executable Targets. I did this by adding /usr/local/Cellar/llvm/10.0.1/Toolchains/LLVM10.0.1.xctoolchain/usr/lib to a project's executable target "Library Search Paths" "Debug" setting.
Have the path to the new tool chain's include directory override the normal standard library's include directory. I haven't confirmed that this is necessary but did this by adding to my library and executable targets' OTHER_CPLUSPLUSFLAGS declaration the value of -nostdinc++ -I/usr/local/Cellar/llvm/10.0.1/Toolchains/LLVM10.0.1.xctoolchain/usr/include/c++/v1. From within Xcode, I'd achieved that by setting the "Other C++ Flags" setting to include this value for the targets of interest. I suspect it's probably safer to make this change at the project level than target level.
Set the COMPILER_INDEX_STORE_ENABLE declaration to NO. This prevented "Unknown argument: '-index-store-path'" errors that stopped builds right from the beginning. I used Xcode's "Enable Index-While-Building Functionality" setting and set it to "No" for this.
Add _LIBCPP_DEBUG=1 to the GCC_PREPROCESSOR_DEFINITIONS declaration for the project. Did this by adding it to Xcode's "Preprocessor Macros" "Debug" setting.
For related Q&A about this, see Is it possible to enable _LIBCPP_DEBUG2 in the current Xcode 4.6.1 toolchain on Mountain Lion?.
I have the following code in eclipse:
I'm running Indigo SR 2, 64bit with CDT Version: 8.0.2.201202111925 Build id: #build#
I have the Java SDK, Android SDK, and C++ CDT.
I Believe the problem is only happening with c++ 11 functions: it seems Eclipse's internal code analyzer CODAN is not properly finding the libraries, even though the compiler is (i have the std=C++11 flag on my compilers).
I think this topic is related: http://www.eclipse.org/forums/index.php/t/490066/
#include <iostream>
#include <array>
using namespace std;
int main(){
cout << "test";
array<int,5> myints;
int x = 0;
cout << "size of myints: " << myints.size() << std::endl;
cout << "sizeof(myints): " << sizeof(myints) << std::endl;
return 0;
}
and I'm getting an error/ not compiling because I'm told:
Symbol 'array' could not be resolved
Why am I not compiling? I'm using eclipse indigo with the CDT and cygwin. I can provide more info as necessary.
UPDATE: I compile through eclipse (hammer button or right click project and click build) using Cygwin GCC and the Cygwin PE Parser.
Update 2: Running in indigo gives both an error in editor and a fail to compile, Kepler gives me the error, but seems to succeed running and compiling. Is there a way to make the error go away in kepler? Also, how would I get the actual command being passed to the compiler from within eclipse?
Update 3: More weirdness, after compiling in Kepler, it now compiles in indigo as well, though the errors persist in the text editor in both version.
1) Is there a way I can make these errors more accurate to the compile?
2) I can press f3 on the include and view it's source, so why can't eclipse seem to find the array symbol?
3) I'm also being told that the first std::endl is an Invalid overload of 'std::endl'
Update 4: I tried std::tr1::array<int, 3> arr1 = {1, 2, 3}; and it's still telling me that array cannot be resolved. I've added -std=c++11 to my c/C++ Build -> Settings -> Cygwin C++ Compiler -> Miscellaneous -> Other flags. It now reads: -c -fmessage-length=0 -std=c++11 But I'm seeing no change at this point
Update: This question seems to be getting at the problem:
Eclipse C/C++ Shows Errors but Compiles?
However, I've added a link to the directory "D:/Wamp/cygwin64/lib/gcc/x86_64-pc-cygwin/4.8.2/include" and it hasn't changed anything...
Thanks!
I think I got this resolved by changing the following settings:
Project->Properties->C/C++ General/Preprocessor Include Paths, Macros Etc. -> Providers (tab)
Then "CDT GCC Built-in Compiler Settings" -> click the link "Workspace Settings"
"CDT GCC Built-in Compiler Settings" (again), under "Command to get compiler specs:"
add: "-std=c++11"
It took a refresh and then the little red squiggles went away.
This was the source:
http://www.eclipse.org/forums/index.php/mv/msg/373462/909018/#msg_909018
I also tried following this:
http://scrupulousabstractions.tumblr.com/post/36441490955/eclipse-mingw-builds
but it didn't exactly work. Probably because I'm on Ubuntu.
I had added "-std=c++11" to the end of the "Command to get compiler specs" within Workspace Settings > C/C++ > Build > Settings > Discovery (tab) > CDT GCC Built-in Compiler Settings"...
And I had set my project so "Enable project specific settings" was disabled, under Properties > C/C++ General.
But still I got C++11 related CODAN errors.
I just discovered that unchecking "Enable project specific settings" does not guarantee the project will use the Discovery settings from the workspace. You still have to go in your project to Properties > C/C++ General > Preprocessor Include Paths, Macros etc. > Providers (tab) > CDT GCC Built-in Compiler Settings ... and make sure the option "Use global provider shared between projects" is checked (which it is not by default on my system, running Eclipse IDE for C/C++ version 2019-09 R). With this option checked "CDT GCC Built-in Compiler Settings" now shows [ Shared ] next to it.
There are a few other discovery providers where you need to set a similar option to ensure [ Shared ] shows up in the list (if you are trying to have your workspace settings apply). The "CDT User Settings Entries" I leave as project-specific, but the others I share in order to use the workspace-level settings.
CODAN is now working properly, and I no longer need to manually "freshen" the indexes and/or add #include statements to nudge CODAN along.
C/C++ Build -> Settings -> Tool Settings -> Cross G++ Compiler -> Dialect -> Language standart -> select which one you want to use.
You don't need to add "-std=c++11" anywhere else
How can I use C++11 when programming the Arduino?
I would be fine using either the Arduino IDE or another environment. I am most interested in the core language improvements, not things that require standard library changes.
As of version 1.6.6, the Arduino IDE enables C++11 by default.
For older versions, read on:
It is very easy to change the flags for any element of the toolchain, including the assembler, compiler, linker or archiver.
Tested on the Arduino IDE version 1.5.7 (released on July 2014),
Locate the platform.txt file,
AVR architecture => {install path}\hardware\arduino\avr\platform.txt
SAM architecture => {install path}\hardware\arduino\sam\platform.txt
Inside that file, you can change any flag, for instance,
compiler.c.flags for changing the default compilation flags for C++ files.
compiler.cpp.flags for changing the default compilation flags for C++ files.
You can also change any of the "recipes" or compile patters, at the corresponding section of the configuration file, under the title "AVR/SAM compile patterns".
After making the changes, you must restart the Arduino IDE, at least on version 1.5.7.
For instance,
To enable support for C++11 (C++0x), tested on Arduino IDE versions 1.5.7 and 1.5.8, you will simply add the flag "-std=gnu++11" at the end of the line starting with compiler.cpp.flags=".
It is expected that C++11 is enabled by default in the near future on the Arduino IDE. However, as of version 1.5.8 (Oct 2014) it is still not the case.
Arduino IDE 1.6.6 and newer have C++11 enabled by default (they have the compiler flag "-std=gnu++11" set in the platform.txt file).
Firstly, only GCC 4.7 and above (and therefore AVR-GCC 4.7 and above) support C++11. So, check the versions installed with:
gcc --version
avr-gcc --version
If AVR-GCC is 4.7 or higher, then you may be able to use C++11.
The Arduino IDE does not support custom compiler flags. This has been requested, but has not yet been implemented.
So, you are left with having to use other environments or to compile your program directly from the command line.
In case, of compiling directly from the command line using AVR-GCC, you simply need to add an extra compiler flag for enabling C++11 support.
-std=c++11
For specific development environments, most would support editing of the compiler flags from the build options within the IDE. The above mentioned flag needs to be added to the list of flags for each environment.
C++0x was the name of working draft of the C++11 standard. C++0x support is available GCC 4.3 onwards. However, this is strictly experimental support so you cannot reliably expect C++11 features to be present. Here is the complete list of features available with the corresponding version of GCC. The availability of features in AVR-GCC will be the same as what's available in the corresponding GCC version.
The compiler flag for C++0x is:
-std=c++0x
Please, note, that there is no easy way to specify additional flags from Arduino IDE or use other IDE (Eclipse, Code::Blocks, etc.) or command line.
As a hack, you can use a small proxy program (should be cross-platform):
//============================================================================
// Name : gcc-proxy.cpp
// Copyright : Use as you want
// Description : Based on http://stackoverflow.com/questions/5846934/how-to-pass-a-vector-to-execvp
//============================================================================
#include <unistd.h>
#include <iostream>
#include <vector>
#include <fstream>
using namespace std;
int main(int argc, char *argv[]) {
vector<string> arguments;
vector<const char*> aptrs;
// Additional options, one per line
ifstream cfg((string(argv[0]) + ".ini").c_str());
if (cfg.bad())
cerr << "Could not open ini file (you're using proxy for some reason, er?)" << endl;
string arg;
while (cfg) {
getline(cfg, arg);
if(arg == "\r" || arg == "\n")
continue;
arguments.push_back(arg);
}
for (const string& arg : arguments)
aptrs.push_back(arg.c_str());
for (int i = 1; i < argc; ++i)
aptrs.push_back(argv[i]);
// Add null pointer at the end, execvp expects NULL as last element
aptrs.push_back(nullptr);
// Pass the vector's internal array to execvp
const char **command = &aptrs[0];
return execvp(command[0], command);
}
Compile the program.
Rename the original avr-g++.exe to avr-g++.orig.exe (or any other name).
Create avr-g++.ini file where the first line is FULL path to the original program (e.g. D:\Arduino\hardware\tools\avr\bin\avr-g++.orig.exe) and add additional parameters, one per line, as desired.
You're done!
Example avr-g++.ini:
D:\Arduino\hardware\tools\avr\bin\avr-g++.orig.exe
-std=c++0x
I use Ino and this worked:
ino build -cppflags="-std=c++0x"
This generated a hex file at least 15k in size (that's with optimizations turned on), compared to about 5k for the standard build, which is a consideration for a poor little ATmega328. It might be okay for one of the microcontrollers with a lot more program space.
If you need more control and a better IDE, I recommend using Sloeber Plugin for Eclipse or the Sloeber IDE itself.
Creating more complicated code is much easier using this IDE. It also allows to add flags to the compiler (C, C++ and linker). So to customize the compile, just right click on project and select Properties. In the Properties window, select Arduino → Compiler Option. This way you can add options to your build.
My C++ application compiles and runs as expected in Netbeans. However, Code Assistance does not recognize terms such as cbegin(), cend(), unordered_set, as evinced by red underscores:
Code assistance does recognize end(), however. To no avail, I have tried going to Project -> Properties -> Code Assistance -> C++ Standard -> C++11. What else should I update or configure to let Netbeans Code Assistance recognize these terms?
Make shure you use a Netbeans Version >= 7.2 because the the C++11 support was introduced in this version (see "C/C++").
If you already have set the C++ standard to C++11 in NB, you can reparse your procject:
Selcect your C++ Project --> right click
Code Assistance -> Reparse Project
Edit:
I tested the methods with the following code under NetBeans 7.3 RC1 (using GCC 4.7.2):
#include <iostream>
#include <list>
int main ()
{
std::list<int> mylist = {5,10,15,20};
std::cout << "mylist contains:";
for (auto it = mylist.cbegin(); it != mylist.cend(); ++it)
std::cout << ' ' << *it;
std::cout << '\n';
return 0;
}
With C++ Standard set to default this fails, but with C++11 (Project Properties -> Build -> C++ Compiler -> C++ Standard = C++11)it works.
Couple of points I kept in mind when I started out with NetBeans and C++11
Make sure its the latest(NetBeans 7.2.1)
Do not use Cygwin to include the GCC libraries to compile your programs. Use the MinGW installer instead. Also make sure to 'Download the latest packages' from the internet when using the MinGW installer.
After installation, make sure that the environment path variables are
set correctly.
Open NetBeans and go to Tools-> Options. Click on the C/C++ Tab and make sure that MinGW is being used as the default compiler.
Right click on your project and select Properties. Select the
C++ Compiler option and make sure that you have written -std=c++11 in the Additional options space