VSCode C++ Intellisense can't discern C++20 features - c++

I try to run codes like
#include <string>
#include <iostream>
int main() {
std::string str = "This is a string";
std::cout << str.starts_with("name");
}
But intellisense will give out an error
"std::__cxx11::basic_string<char, std::char_traits,
std::allocator>" has no member "starts_with" C/C++(135) [6,9]
And It still can be build and produce a correct result.
Also it can find implementation in header file.
But the macro __cplusplus is defined as 201703L
I've already added a command -std=c++20 when building, why this happened?
Compiler: minGW 11.2 compiled by msys2

Assuming you are using Microsoft's C/C++ extension, you must configure the extension to use C++ 20 standard for intellisense.
The easiest way to do this is to add the line "C_Cpp.default.cppStandard": "c++20" to your settings.json file. You can also find the setting in the GUI under the name "Cpp Standard". Selecting c++20 from its dropdown will achieve the same result.
Note that this setting is, by default, set as a global user defaults. You can configure it per-workspace by selecting the Workspace tab in the settings GUI and changing that Cpp Standard dropdown to c++20.
As for why adding the -std=c++20 flag didn't work: -std=c++20 just tells your compiler which standard to use to build your code. 'Intellisense' does not receive this flag because it is a separate tool from the compiler and is therefore not required to support all the standards the compiler supports. It may support less even, although Intellisense tools usually support as current a standard as possible. Therefore the language standard for Intellisense must be configured separately from the compiler (in this case).
Final Note: After changing the setting, try closing and re-opening VS Code. In my experience changing the language standard setting can cause some weirdness to happen. Closing and re-opening VS Code seems to ensure the setting changes take full effect.

Related

How to enable C++17 code generation in VS2019 CUDA project

I am moving some code from VS2017 on one pc to another pc with VS2019. Everything is fine excepted that I cannot use std::filesystem. In my former code, I was using C++14 and had std::experimental::filesystem. In the new code, I want to move to C++17 so I changed to std::filesystem (as shown in my code below). The weird thing is that intellisense (not sure it is the right name of the thing) shows no error. It even displays filesystem when I type std::f...
But the code won't build and give the error "namespace "std" has no member "filesystem"".
I changed C++ Language Standard to c++latest, VS2019 version is Community 16.6.5.
#include <string>
#include <iostream>
#include <filesystem>
namespace fs = std::filesystem;
int main()
{
std::string path = "C:\\";
for (const auto& entry : fs::directory_iterator(path))
std::cout << entry.path() << std::endl;
}
EDIT: The last line of my initial question might not have been clear enough: I already changed "C++ Language Standard" to C++17 or C++latest.
EDIT: As requested, the output:
Thanks to #drescherjm, we found that it is a Cuda issue. Any idea from a Cuda specialist?
Using CUDA 11, the nvcc compiler-driver is capable of supporting usage of certain C++17 language features. Currently, in VS2019, this doesn't appear to be the default behavior.
The following method should work to enable C++17 support when compiling a cuda project in VS2019:
go to Project..Properties..Configuration Properties...CUDA C/C++...Command Line Then you will see a box in the right hand side bottom of the dialog labelled "Additional Options". In that box, type the following:
-std=c++17 -Xcompiler "/std:c++17"
then click "Apply" then rebuild.
(These instructions may change for future versions of CUDA or future versions of Visual Studio.)
Note that this method applies to CUDA projects only (i.e. when nvcc is invoked for compilation), and should be workable whether your code is in a file ending in .cpp or in a file ending in .cu. For non-CUDA projects, this may be helpful.
The std::filesystem features appear to require C++17. The CUDA nvcc compiler-driver is documented here.

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.

Orwell Dev C++ doesn't work with C++11

I'm trying to use any of the C++11 features in Orwell Dev C++ but with no luck. I installed the version with minGW and whatever I set in the compiler options, I just get the "[Error] 'to_string' was not declared in this scope" in this code:
#include<iostream>
#include<string>
using namespace std;
int main()
{
string test = to_string(5);
}
I tried setting -std=gnu++11 and -std=c++0x but neither does the job. What's the most curious is that when I click on to_string, it shows me the overloaded functions - for long, float, int and so on. Thus, it must somehow get what the function does - how come it doesn't compile it, then? The compiler is set correctly to MinGW GCC 4.7.2 (the one bundled with the installer).
If you want to use C++11 in Dev-C++ you should to this steps:
Go to Tools > Compiler Options
Go to the tab Settings > Code Generation
Change the parameter Language Standard (-std) to ISO C++11
It is a known bug that to_string does not work with MinGW yet (which is actually GCC's fault, to a degree):
http://sourceforge.net/p/mingw/bugs/1578/
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=52015
Intellisense is often driven by a different engine than the compiler (as very few compilers have hooks to make intellisense easy), so that's likely why you're seeing it in your IDE when it's not supported by your compiler.

How can I use a C++11 to program the Arduino?

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.