Unable to build a gtkmm program that uses std::make_unique - c++

I have been programming using Gtkmm for a while now, using C++11 features without problems. Today, I added a line of code using the C++14 feature std::make_unique and got a compiler error. At first, I thought I had an issue with my build configuration but after some testing, I narrowed it down to Gtkmm. Here is code that builds fine on my system:
Build command:
g++ -std=c++14 main.cpp
Code:
#include <memory>
int main()
{
std::unique_ptr<int> intPtr;
intPtr = std::make_unique<int>(3);
return 0;
}
If I switch to this build command:
g++ -std=c++14 main.cpp `pkg-config gtkmm-3.0 --cflags --libs`
The code no longer builds. I get the following errors:
main.cpp: In function ‘int main()’:
main.cpp:7:14: error: ‘make_unique’ is not a member of ‘std’
intPtr = std::make_unique<int>(3);
^
main.cpp:7:31: error: expected primary-expression before ‘int’
intPtr = std::make_unique<int>(3);
What's the problem with Gtkmm? For your information, I am using g++ v 5.4.0 and gtkmm 3.0.
EDIT: It seems this is not C++14 related. I tried building with other C++14 features, like [[DEPRECATED]] and it worked fine. Maybe only the standard library... I also tried switching to g++ 7 and got the same errors.

You are probably running into a problem with the C++ standard that is specified by the --cflags argument in pkg-config gtkmm-3.0 --cflags --lib. If -std=c++11 or something older is the result of providing the --cflags option, then it will override any earlier specifications. You can probably fix the problem just by placing your desired specification at the end:
g++ main.cpp `pkg-config gtkmm-3.0 --cflags --libs` -std=c++14

Related

How do I compile with C++98 on MacOS?

I need to use C++98 for university programs, however even when passing the -std=c++98 flag to clang++ or to g++ it still seems to compile with c++11 and does not give errors if I use c++11 features. Here is a simple example:
#include <string>
#include <sstream>
using namespace std;
int main()
{
int i;
string number = "12";
i = stoi(number);
}
My makefile:
all:
clang++ -std=c++98 -c *.cpp
clang++ -o main *.o
clean:
rm -f *.o main
run: clean all
./main
Then I run the command make from Terminal (I tried using clang++ instead of g++ but it yields the same result) and receive the following output:
➜ cppversion make
g++ -std=c++98 -c *.cpp
g++ -o main *.o
➜ cppversion make
clang++ -std=c++98 -c *.cpp
clang++ -o main *.o
➜ cppversion
I believe this code should not have compiled if the -std=c++98 flag was working. How do I force code to compile with c++98?
Here is the version of clang:
Apple clang version 12.0.5 (clang-1205.0.22.11)
Target: x86_64-apple-darwin20.2.0
Thread model: posix
InstalledDir: /Library/Developer/CommandLineTools/usr/bin\
Here is the version of g++:
Configured with: --prefix=/Library/Developer/CommandLineTools/usr --with-gxx-include-dir=/Library/Developer/CommandLineTools/SDKs/MacOSX11.1.sdk/usr/include/c++/4.2.1
Apple clang version 12.0.5 (clang-1205.0.22.11)
Target: x86_64-apple-darwin20.2.0
Thread model: posix
InstalledDir: /Library/Developer/CommandLineTools/usr/bin
I have also tried adding the flag -pedantic but it does not fix the problem.
Using the flag -stdlib=libc++ yields the following:
➜ cppversion make
clang++ -stdlib=libstdc++ -std=c++98 -c *.cpp
clang: warning: include path for libstdc++ headers not found; pass '-stdlib=libc++' on the command line to use the libc++ standard library instead [-Wstdlibcxx-not-found]
main.cpp:1:10: fatal error: 'string' file not found
#include <string>
^~~~~~~~
1 error generated.
make: *** [all] Error 1
If I change it to just -stdlib=libc++ then it still compiles:
➜ cppversion make
clang++ -stdlib=libc++ -std=c++98 -c *.cpp
clang++ -o main *.o
➜ cppversion
I found an easy solution: Use homebrew to install gcc and use g++-11 to compile.
Try using -std=c++98 -pedantic.
This should strictly enforce the specific standard.
Disclaimer: This is partly guesswork since I don't have a Mac
From my understanding, clang++ is the default compiler on Mac and I would therefore not be surprised if even g++ uses LLVM:s libc++ and headers by default. std::stoi is unconditionaly declared in the libc++ headers.
If you instead useg++:s libstdc++ toolchain, you will probably get the error you want:
clang++ -stdlib=libstdc++ -std=c++98 -o main main.cpp
I found an easy solution: Use homebrew to install gcc and use g++-11 to compile.

Compiling a c++ including root libraries with g++

I am trying to compile a c++ program, which uses the TF1 library of the ROOT-framework, with the g++ compiler.
I tried
I already tried
g++ a.cpp -o 'root-config --cflags --glibs'
But that just gives me the error
g++: error: no such file or directory: 'root-config --cflags --glibs'
I am very new to both ROOT and C++ so help is very mucha appreciated!
You must check with:
g++ a.cpp $(root-config --cflags --glibs) -o a

How to use OpenCV train_hog.cpp

I'm trying to use OpenCV train_HOG utility.
When I try to compile it with
g++ -ggdb `pkg-config --cflags --libs opencv` train_HOG.cpp -o train_HOG
I get a ton of different errors.
train_HOG.cpp:11:21: error: ‘ml’ is not a namespace-name
using namespace cv::ml;
^
train_HOG.cpp:11:23: error: expected namespace-name before ‘;’ token
using namespace cv::ml;
And a few pages more.
Can anyone give me instructions how to use it properly or point me to a working solution?

Compiling CImg with c++0x and MingW

I am trying to compile the following CImg sample code with std=c++0x and MingW:
#include "CImg.h"
using namespace cimg_library;
int main() {
CImg<unsigned char> img(640,400,1,3);
img.fill(0);
unsigned char purple[] = { 255,0,255 };
img.draw_text(100,100,"Hello World",purple);
img.display("My first CImg code");
return 0;
}
When I compile using:
g++ -std=c++0x HelloWorld.cpp -lgdi32
I get the following error:
error: '_fileno' was not declared in this scope
But when I compile without std=c++0x, it works perfectly:
g++ HelloWorld.cpp -lgdi32
How can I compile CImg with c++0x enabled?
I think that gnu++0x or gnu++11 should be available under under GCC 4.5.x and with that you should be able to compile CImg with a possibility to use C++11 (I just checked under my own MinGW installation, however I'm using 4.8. Could you consider upgrading?). So you could simply use:
g++ -o hello_world.exe HelloWorld.cpp -O2 -lgdi32 -std=gnu++0x
Or:
g++ -o hello_world.exe HelloWorld.cpp -O2 -lgdi32 -std=gnu++11
EDIT
I just checked and -std=gnu++11 option is available since GCC 4.7, but I believe you should be fine with -std=gnu++0x under 4.5.x.

unique_ptr compile error

I guess this is embarrassing if I told you I cant get this to compile. would you please help me:
#include<memory>
using namespace std;
int main()
{
std::unique_ptr<int> p1(new int(5));
return 0;
}
$ gcc main.cpp
main.cpp: In function ‘int main()’:
main.cpp:6:2: error: ‘unique_ptr’ was not declared in this scope
main.cpp:6:13: error: expected primary-expression before ‘int’
main.cpp:6:13: error: expected ‘;’ before ‘int’
$ gcc --version
gcc (Ubuntu/Linaro 4.6.1-9ubuntu3) 4.6.1
This is just a guess.
Most likely you compiled your program like this (or similarly) :
g++ main.cpp
If you did, then the problem is that g++ uses c++03 as default. To use c++11 features (and std::unique_ptr), you need to use newer version of c++ :
g++ -std=c++11
or
g++ -std=c++14
and I would recommend to use also -Wall -Wextra -pedantic.
If you are using Code::Blocks, go to Settings > Compiler > Global compiler settings > Compiler settings and look for the Have g++ follow the C++11 ISO C++ language standard [-std=c++11] and check it!
(Code::Blocks will add the -std=c++11 for you when compiling)