How do I enable C++17 in Xcode for Mac OSX? - c++

How do I enable C++17 in Xcode (9.4.1) on OSX High Sierra (10.13.5)?

Steps to use C++17 in Xcode (9.4.1) on OSX High Sierra (10.13.5):
Open existing or create a new C++ project in Xcode
Click on the "show project navigator" button. It is located on the top-left section of Xcode window just below the minimize/maximize/close window buttons. It is the left-most icon and looks like a folder.
Click on "Build Settings" and scroll down to find and expand the section "Apple LLVM 9.0 - Language - C++"
Change the C++ Language Dialect combobox selection to "C++17 [-std=c++17]"
Verification steps:
Now when I output __cplusplus, I see 201703, and I am able to compile C++17 features, such as if constexpr.
template<class T>
int compute(T x) {
if constexpr( supportsAPI(T{}) ) {
// only gets compiled if the condition is true
return x.Method();
} else {
return 0;
}
}
int main(){
cout << __cplusplus << endl;
return 0;
}
Output:
201703
Program ended with exit code: 0

When using development CocoaPods (writing a C++ library) I had also to update podspec of this library containing c++ 17 code to make compile host application which included this pod.
So I added these flags to library's podspec
spec.xcconfig = {
"CLANG_CXX_LANGUAGE_STANDARD" => "c++17",
"CLANG_CXX_LIBRARY" => "libc++"
}

Related

std::to_chars compile error on Mac citing availability

In an Xcode 14 project that has the C++ language set to C++20 and deployment target set to macOS 10.14, this code:
#include <charconv>
static void foo()
{
if (__builtin_available( macOS 10.15, *))
{
char buffer[10];
std::to_chars_result tcr = std::to_chars( buffer, buffer+5, 5 );
}
}
produces an error message:
'to_chars<int, 0>' is unavailable: introduced in macOS 10.15
(The code does compile if the deployment target is set to 10.15.) I thought the __builtin_available check was supposed to allow me to use functions introduced in macOS 10.15. Why isn't that working?

Why Xcode 11 beta can't use C++17's <filesystem> header?

I need to use C++ 17's filesystem header for my project. As far as I know, Apple finally made it available with Xcode 11 and with macOS Catalina. I'm on the latest (beta 3) Xcode 11 and I use macOS Catalina public beta 2, so in theory it should work. But for some reason it's not, and Xcode gives errors like:
'~path' is unavailable: introduced in macOS 10.15
If I set the C++ standard library in Build Setting to libstdc++ from libc++ these error emssages gone and I got a warning:
include path for stdlibc++ headers not found; pass '-stdlib=libc++' on the command line to use the libc++ standard library instead
and a ton of errors with missing iostream and cstddef in various files. What could I do to make filesystem work?
Edit: a minimal code example
#include <filesystem>
#include <iostream>
#include <string>
bool isPathDir(std::string pathString);
int main(int argc, char *argv[])
{
std::string pathString = "../test.jpg";
if (isPathDir(pathString)) {
std::cout << "This is a directory!" << std::endl;
} else {
std::cout << "This is not a directory" << std::endl;
}
}
bool isPathDir(std::string pathString)
{
std::filesystem::path path(pathString);
return std::filesystem::is_directory(path);
}
Promoting my comment into an answer:
Do you happen to have a back-deployment target older than macOS 10.15 specified? This would appear on your command-line as something like -mmacosx-version-min=<value>.
#LouisDionne Oh yes, that was the problem! As soon as I set the deployment target to 10.15 the code build perfectly! I've never heard of deployment targets before, thank you very much!
Just to explain what's going on here, the issue is that support for <filesystem> was only introduced in Mac OS 10.15. When you use -mmacosx-version-min=XYZ, you tell the compiler that your program should be able to run on versions of Mac OS all the way until version XYZ. If you use a version older than 10.15, we nicely tell you at compile-time that you can't use <filesystem>, because that would be a runtime error (likely symbol missing from libc++.dylib) if you tried running the program on a version of Mac OS older than 10.15.

Including code to be compiled only if static constexpr is met C++

Is it possible to include code to be compiled only if a static constexpr has a certain value?
Take this for instance
static constexpr auto VERSION_MIN = 123;
If the number were set to 124 include the code to be compiled otherwise exclude it.
Basically I have two source packages which are identical except for a few lines of code which are considered extra or a minor difference.
I just want to make a universal application where I don't need to recompile to switch versions.
How would I check to see if a constexpr is equal to 124, would I just use a basic control structure? Or is there another way to do this?
The following works with gcc 4.9:
static constexpr auto VERSION_MIN = 123;
void myFunction()
{
if (VERSION_MIN == 123) {
printf("This is version 123\n");
}
else {
printf("This is another version\n");
}
}
On Linux (don't now such tools for Win) you can check that the binary does not contain the string "This is another version\n".
Thus you can replace
#ifdef VERSION_MIN 123
printf("This is version 123\n");
#else
printf("This is another version\n");
#endif
My IDE (QtCreator) handle the "pure" C++ code better than the preprocessor code.
Microsoft Visual Studio 2015 (If you are using it) has solved this problem with Build Configurations. You can create a new Build Configuration and then give it a preprocessor directive to insert automatically into the code when it builds. This will allow you to create a different Build Configuration for each 'Version' of your code and then you can 'batch build' to build each version; without changing the actual source code for each version.
To do this go to Configuration Manager (Under Release/Debug Dropdown) then then give your Version a name and copy settings from your previous building configuration. After you have created a Build Configuration select it in the Configuration drop down to make it active and then go to Project Properties (Alt+p+p) -> C/C++ -> Preprocessor -> Preprocessor Definitions and add a preprocessor to control what code is compiled in that version and what isn't.
#ifdef _DEBUG
std::cout << "data data data" << std::endl;
#endif //_DEBUG

How to use GMP library in dev c with gcc4.7.2

I have absolutely no idea about using gmp. Need some functions for a project and need a quick installation guide. I am Absolutely beginner to this field so please help accordingly.
I have:
Dev C++ 5.4.2 in windows 8.1 configuration with GCC4.7.2 as default
compiler.
gmp-static-mingw-4.1.tar
Please specify the correct procedure to configure gmp library.
At first put gmp.h into ..\Dev-Cpp\MinGW32\include and both libgmp.a and libgmp.la into ..\Dev-Cpp\MinGW32\lib directory, then create some project in DevCpp, for example:
#include <stdio.h>
#include <gmp.h>
int main(void)
{
mpz_t x;
mpz_init(x);
mpz_set_str(x, "12345", 10);
mpz_mul_ui(x, x, 2);
gmp_printf("%Zd\n", x);
mpz_clear(x);
return 0;
}
After that go to Project Options -> Parameters and click Add Library of Object:
From the list select libgmp.a file (your static library) and click Open:
Compile and run you project, you will see some note about Makefile update, simply confirm.
Note that GMP 4.1 is now rather old, consider latest version and/or manual compilation for best possible performance on your configuration.

XCode std::thread C++

For a small project for school I need to create a simple client / server construction which will run on a router (with openWRT) and I am trying to do something with threads in this application.
My C++ skills are very limited, so I found this on the internet as an basic example.
#include <thread>
#include <iostream>
void doSomeWork( void )
{
std::cout << "hello from thread..." << std::endl;
return;
}
int main( int argc, char *argv[] )
{
std::thread t( doSomeWork );
t.join();
return 0;
}
When I try to run this in Xcode (4.5.2) I get the following error:
Attempt to use an deleted function
And it shows some code of:
__threaad_execute(tuple<_Fp, _Args...>& __t, __tuple_indices<_Indices...>)
{
__invoke(_VSTD::move(_VSTD::get<0>(__t)), _VSTD::move(_VSTD::get<_Indices>(__t))...);
}
I think I need to do something with 'build settings' or 'link library' or something? But I am not quite sure what to do exactly. I thought I might need to set the following settings (which i found here)
In the Build Settings tab for your project, scroll down to "Apple LLVM Compiler 4.1 - Language"
Set the setting "C++ Language Dialect" to "C++11 [-std=c++11]"
Set the setting "C++ Standard Library" to "libc++ (LLVM standard C++ library with C++11 support)"
But those settings where already set.
Is there any flag / library or something I am missing?
Use G++ instead of LLVM in XCode. Don't forget to link thread libs (-lpthread - or -pthread, -lrt) in compiler build settings. And count with the differences of thread behaviour across Win/Mac/Linux OS (despite it's POSIX)