Compiling CImg with c++0x and MingW - c++

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.

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.

Unable to build a gtkmm program that uses std::make_unique

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

Clangs C++ Module TS support: How to tell clang++ where to find the module file?

In his talk at CppCon, Richard Smith mentioned that even though the Module TS support is currently work in progress, it can already be used. So I build clang 4.0 from svn and tried it on a very simple example. In my myclass.cppm file I defined a simple wrapper for an int
module myclass;
export class MyClass {
public:
MyClass (int i)
: _i{i} {}
int get() {
return _i;
}
private:
int _i;
};
and my main.cpp just creates one instance of that class and outputs its held int to std::cout.
#include <iostream>
#include <string>
import myclass;
int main(int, char**) {
MyClass three{3};
std::cout << std::to_string(three.get()) << std::endl;
}
Then I tried to compile it via clang++ -std=c++1z -fmodules-ts main.cpp and with clang++ -std=c++1z -fmodules-ts myclass.cppm main.cpp but that doesn`t work and I get the same error message in both cases:
main.cpp:3:8: fatal error: module 'myclass' not found
import test.myclass;
~~~~~~~^~~~
1 error generated.
Unfortunately I have not been able to find documentation for -fmodules-ts. Does someone know how I can get clang++ to compile my simple example?
You can compile it as follows:
clang++ -std=c++1z -fmodules-ts --precompile -o myclass.pcm myclass.cppm
clang++ -std=c++1z -fmodules-ts -fmodule-file=myclass.pcm -o modules_test main.cpp
However, this can't be how it's meant to work since you'd manually need to encode the dependency hierarchy of your modules in the calls to the compiler; I'd be very interested in the correct answer to this question :-).
-fprebuilt-module-path works even though it fires a warning: "argument unused during compilation: '-fprebuilt-module-path=.'"
The complete command was:
clang++-4.0 -std=c++1z -fmodules-ts -fprebuilt-module-path=. -o modules_test main.cpp
as of 27th of December, 2017 I have checked out the latest llvm branch, built it on my macbook and then eexecuted the following:
./../bin/clang++ -std=c++17 -fmodules-ts --precompile -o myclass.pcm myclass.cppm
./../bin/clang++ -std=c++17 -fmodules-ts -c myclass.pcm -o myclass.o
./../bin/clang++ -std=c++17 -fmodules-ts -fprebuilt-module-path=. -o main main.cpp hello.o
and tada, worked prefectly without any warnings or errors.

where does unique_ptr live?

I'm trying to compile some code (below) using gcc 4.6.2 on OSX 10.6.5. It's trivial; but the compiler cannot find unique_ptr.
#include <memory>
int main(int argc, char** argv)
{
std::unique_ptr<bar> foo(new bar(0));
}
I compile as such:
c++ main.cpp -o ./bin/main -std=gnu++0x -ansi -pedantic -Wall -Wno-long-long -Wno-deprecated -O3 -ansi -DNDEBUG -I/usr/include -I/opt/local/include
I tried explicitly including bits/unique_ptr but that leads me to an error saying GXX_EXPERIMENTAL_CXX0X is undefined. Huh? As you can see above, I explicitly ask for gnu++0x. I've also tried "-std=c++0x" with identical results.
What am I doing wrong?
Your command has -ansi (which is equivalent to -std=c++98), and this overrides -std=c++0x. Try removing it.

mingw linker error when using vector templates

I'm using MinGw on Windows 7. The following simple program compiles fine, but the linker complains and I do not understand what's wrong:
#include <iostream>
#include <vector>
using namespace std;
int main()
{
std::vector<int> iv;
iv.push_back(7);
cout << iv.back() << endl;
return 0;
}
the compiler/linker messages look as follows:
mingw32-g++.exe -Wall -fexceptions -std=c++0x -Wall -g -std=c++0x -Wall -g -frepo -IC:\cppbuchincludes\include -IG:\Boost -IG:\Users\thomas\cpp\STLUsage\\include -c G:\Users\thomas\cpp\STLUsage\main.cpp -o obj\Debug\main.o
mingw32-g++.exe -o bin\Debug\STLUsage.exe obj\Debug\main.o G:\Boost\stage\lib\libboost_filesystem-mgw45-mt-d-1_45.dll.a G:\Boost\stage\lib\libboost_regex-mgw45-mt-d-1_45.dll.a G:\Boost\stage\lib\libboost_system-mgw45-mt-d-1_45.dll.a G:\Boost\stage\lib\libboost_thread-mgw45-mt-1_45.dll.a G:\Boost\stage\lib\libboost_unit_test_framework-mgw45-mt-d-1_45.dll.a
collect: recompiling G:\Users\thomas\cpp\STLUsage\main.cpp
collect: relinking
collect2: '_ZNSt12_Vector_baseIiSaIiEEC1Ev' was assigned to 'obj\Debug\main.rpo', but was not defined during recompilation, or vice versa
obj\Debug\main.o: In function `vector':
c:/mingw/bin/../lib/gcc/mingw32/4.5.2/include/c++/bits/stl_vector.h:208: undefined reference to `std::_Vector_base<int, std::allocator<int> >::_Vector_base()'
(...and so on...)
I can use templates I defined myself.
I have that MinGw binary from a book and followed the instructions in that book regarding compiler settings. In particular the references to the Boost libs are taken from there.
This must be a simple thing, I just want to make trivial use of the STL.
Edit following the advice given in an answer, I replaced the binary to be used to compile by g++.exe in the Settings -> Compiler and debugging -> toolchain executables dialog, but I'm getting the same error messages (with mingw32-g++.exe now replaced by g++.exe).
Edit (once more) this has to be problem eith the Code::Blocks settings, since compiling using g++ from the command line works just fine.
Use g++ to compile and link the program. mingw32-g++.exe doesn't do that.
FAQ says,
What's the difference between gcc and mingw32-gcc?
The mingw32-gcc, mingw32-g++, etc. binaries exist as an aid to cross development. They are created in a typical build of gcc. They are therefore distributed as the maintainers of GCC meant them to be. The gcc.exe indicates that the binary produces binaries for a target equal to the build, while the mingw32-gcc binary produces binaries to be executed on the mingw32 target.
So I guess the problem is because of mingw32-g++.exe which you're not supposed to use, for normal build.
Try these:
g++ program.cpp //simple build
g++ program.cpp -Wall //build with all warnings enabled
g++ program.cpp -Wall -O2 //enable warnings and optimization level 2
g++ program.cpp -std=c++0x //use C++11 features
Hope that helps.