How can I cross compile on Linux for Windows with code that uses C++11 features? So far I've attempted the following:
#include <stdio.h>
class foo
{
public:
const char* getstr() { return "hello world"; }
};
int main()
{
printf("Hello, World!\n");
foo f;
f.getstr();
auto q = f.getstr();
return 0;
}
This fails to build with:
i586-mingw32msvc-g++ cpp11_test.cpp
cpp11_test.cpp: In function ‘int main()’:
cpp11_test.cpp:15: error: ISO C++ forbids declaration of ‘q’ with no type
cpp11_test.cpp:15: error: invalid conversion from ‘const char*’ to ‘int’
No problem I thought, I just need the -std=c++11 option:
i586-mingw32msvc-g++ cpp11_test.cpp -std=c++11
cc1plus: error: unrecognized command line option "-std=c++11"
Still no luck, --version output is:
i586-mingw32msvc-g++ --version
i586-mingw32msvc-g++ (GCC) 4.2.1-sjlj (mingw32-2)
Copyright (C) 2007 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
Is there another option to make this work? Or a new version? How would I get a new version if its not in the package manager, would I have to build a newer compiler from source using the host OS'es compiler?
Related
Hi: I'm using WSL+Ubuntu20.04 on win10, installed g++ using sudo apt-get.
g++ --version
g++ (Ubuntu 9.4.0-1ubuntu1~20.04.1) 9.4.0
Copyright (C) 2019 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
Fairly new, then I have this code modified from cppreference.com:
#include <iostream>
#include <thread>
#include <shared_mutex>
#include <mutex>
using namespace std;
class Counter {
int value;
shared_mutex m;
public:
...
My command line is:
g++ rwlock.cpp -std=c++11
It doesn't compile, saying that:
error: ‘shared_mutex’ does not name a type
10 | shared_mutex m;
And some other errors, all point to that I don't have these c++11 types defined.
Did I missing anything while installing g++ or should add more command line options when compiling?
Thanks!
The std::shared_mutex was not provided until c++ 17. https://en.cppreference.com/w/cpp/thread/shared_mutex
So to fix this issue, you just need to change the compilation command to
g++ rwlock.cpp -std=c++17
I am running ubuntu 16.04 with gcc.
My q.ccp file is
#include <google/protobuf/generated_message_util.h>
#include <google/protobuf/repeated_field.h>
#include <google/protobuf/extension_set.h>
#include <google/protobuf/generated_message_reflection.h>
#include <google/protobuf/generated_message_util.h>
#include <google/protobuf/stubs/common.h>
#include <google/protobuf/descriptor.h>
int main(int argc, char **argv)
{
google::protobuf::Message* msg;
const google::protobuf::Descriptor* message_desc = msg->GetDescriptor();
const google::protobuf::FieldDescriptor * fd_name = message_desc->FindFieldByName("name");
return 0;
}
command used for compilation:
g++ -D_GLIBCXX_USE_CXX11_ABI=0 q.cpp -L/usr/lib/x86_64-linux-gnu /usr/local/lib/libprotobuf.a -lpthread
protoc --version returns: 2.2.0
gcc --version
gcc (Ubuntu 4.8.5-4ubuntu2) 4.8.5
Copyright (C) 2015 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
compile error:
/tmp/cciGJPqq.o: In function `main':
q.cpp:(.text+0x5f): undefined reference to `google::protobuf::Descriptor::FindFieldByName(std::string const&) const'
collect2: error: ld returned 1 exit status
But when I leave the -D_GLIBCXX_USE_CXX11_ABI=0 option, I get no compile error. But the problem is that I running the executable on different system which require compilation with this option for the program to run.
If your compilation succeeds only with D_GLIBCXX_USE_CXX11_ABI=0, then you may be using a shared library (libprotobuf) that is precompiled using the same or using an older ABI, like gcc 4.8.
I would check the g++ version. It may be > 5, which would have the newer ABI.
When trying to install OpenMPI the .configure filed failed in the section checking for ISO C99 ability of the selected compiler.
Puzzled as gcc of course has both the std=gnu99 and std=c99 option, I pruning the 20,000 lines configure file to isolate the offending section. In the end I traced it back to gcc 5 not compiling variable argument functions.
The below code generates the "suffix or operands invalid for `movq'" error, which is the root cause of the .configure file failing.
(The step-by-step installation for OpenMPI I followed is here https://wiki.helsinki.fi/display/HUGG/Installing+Open+MPI+on+Mac+OS+X)
Anyone has seen this and knows how to fix it?
//-----------------------------------------------------------------------------
// This fails to compile with gcc 5.3
//
// Command: gcc test4.c
//
// Error is:
// /var/folders/4s/gkkpz000gn/T//ccAraq59.s:47:suffix or operands invalid for `movq'
// /var/folders/4s/gkg0r000gn/T//ccAraq59.s:52:suffix or operands invalid for `movq'
//
// gcc version is 5.3.0:
//
// $ gcc --version
// gcc (GCC) 5.3.0
// Copyright (C) 2015 Free Software Foundation, Inc.
// This is free software; see the source for copying conditions. There is NO
// warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
//
//-----------------------------------------------------------------------------
// Check varargs
static void
test_varargs (const char *format, ...)
{
}
//--------------------------------------------------------------
// MAIN {}
//--------------------------------------------------------------
int
main ()
{
//====================================================
// Check varargs.
// test_varargs ("s", "string"); //WORKS
// test_varargs ("d' ", 65); //WORKS
// test_varargs ("s, d' ", "string", 65); //WORKS
test_varargs ("f .", 34.234); // FAILS!!!
test_varargs ("s, d' f .", "string", 65, 34.234); //ALSO FAILS
//====================================================
return 0;
}
TLDR: conflict between brew and XCode gcc installs.
I ended up uninstalling all gcc versions installed, deleting g++, deleting all dangling links left over. Next I upgraded from XCode 6 to 7 and used the gcc version coming with it. This fixed the above problem.
Deleting all dangling symlinks and the unziped tar-ball of OpenMPI and then re-unzipping allowed the OpenMPI to be installed without a hitch. cd ./examples, make all, mpirun -np 4 hello_c worked and we have a happy MPI installation.
I understand that if a temporary is bound to a reference member in the constructor's initializer list, the object will be destroyed as the constructor returns.
However, consider the following code:
#include <functional>
#include <iostream>
using callback_func = std::function<int(void)>;
int
func(const callback_func& callback)
{
struct wrapper
{
const callback_func& w_cb;
wrapper(const callback_func& cb) : w_cb {cb} { }
int call() { return this->w_cb() + this->w_cb(); }
};
wrapper wrp {callback};
return wrp.call();
}
int
main()
{
std::cout << func([](){ return 21; }) << std::endl;
return 0;
}
This looks perfectly valid to me. The callback object will live during the whole execution of the func function and no temporary copy should be made for wrapper's constructor.
Indeed, GCC 4.9.0 compiles fine with all warnings enabled.
However, GCC 4.8.2 compiler gives me the following warning:
$ g++ -std=c++11 -W main.cpp
main.cpp: In constructor ‘func(const callback_func&)::wrapper::wrapper(const callback_func&)’:
main.cpp:12:48: warning: a temporary bound to ‘func(const callback_func&)::wrapper::w_cb’ only persists until the constructor exits [-Wextra]
wrapper(const callback_func& cb) : w_cb {cb} { }
^
Is this a false positive or am I misunderstanding the object lifetimes?
Here are my exact compiler versions tested:
$ g++ --version
g++ (GCC) 4.8.2
Copyright (C) 2013 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
$ g++ --version
g++ (GCC) 4.9.0 20140604 (prerelease)
Copyright (C) 2014 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
This is a bug in gcc 4.8 that has been fixed in 4.9. Here is the bug report:
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=50025
As pointed out by Howard Hinnant and already indicated by R Sahu's comment, this is a bug (which used to be required by the then-broken standard; thanks to Tony D for pointing this out) in the way GCC 4.8 is treating initializer lists.
Changing the constructor in my original example from
wrapper(const callback_func& cb) : w_cb {cb} { }
to
wrapper(const callback_func& cb) : w_cb (cb) { }
makes the warning with GCC 4.8.3 go away and the created executable Valgrind clean. The diff of the two assembly files is huge so I don't post it here. GCC 4.9.0 creates identical assembly code for both versions.
Next, I replaced the std::function with a user-defined struct and deleted copy and move constructors and assignment operators. Indeed, with GCC 4.8.3, this retains the warning but now also gives a (slightly more helpful) error that the above line of code calls the deleted copy constructor of the struct. As expected, there is no difference with GCC 4.9.0.
I am beginning Zed Shaw's Learn C The Hard Way. I have downloaded XCode and the Command Line Tools. But when I compile the very first program:
int main(int argc, char *argv[]) {
puts("Hello world.");
return 0;
}
I get this warning:
ex1.c:2:1: warning: implicit declaration of function 'puts' is invalid
in C99
[-Wimplicit-function-declaration]
The program does compile and execute correctly.
I'm using OSX 10.8.3. Entering 'gcc -v' gives:
Using built-in specs. Target: i686-apple-darwin11 Configured with:
/private/var/tmp/llvmgcc42/llvmgcc42-2336.11~182/src/configure
--disable-checking --enable-werror --prefix=/Applications/Xcode.app/Contents/Developer/usr/llvm-gcc-4.2 --mandir=/share/man --enable-languages=c,objc,c++,obj-c++ --program-prefix=llvm- --program-transform-name=/^[cg][^.-]*$/s/$/-4.2/ --with-slibdir=/usr/lib --build=i686-apple-darwin11 --enable-llvm=/private/var/tmp/llvmgcc42/llvmgcc42-2336.11~182/dst-llvmCore/Developer/usr/local
--program-prefix=i686-apple-darwin11- --host=x86_64-apple-darwin11 --target=i686-apple-darwin11 --with-gxx-include-dir=/usr/include/c++/4.2.1 Thread model: posix gcc version 4.2.1 (Based on Apple Inc. build 5658) (LLVM build 2336.11.00)
Please help.
You need to include stdio.h, i.e.
#include <stdio.h>
at the start to import the function definition.
This "book" should be renamed to Learn To Hate C By Following Meaningless Examples That Are Blatantly Wrong.
The correct code in modern C would be plain and easy
#include <stdio.h> // include the correct header
int main(void) { // no need to repeat the argument mantra as they're not used
puts("Hello world.");
} // omit the return in main as it defaults to 0 anyway
While the original example
int main(int argc, char *argv[]) {
puts("Hello world.");
return 0;
}
would have been just plain bad in 1989, in 1999 (that is 18 years prior to the writing of this answer, and almost as many years before the "book" was written) the C standard was revised. In the C99 revision, this kind of implicit function declaration was made illegal - and naturally it remains illegal in the current revision of the standard (C11). Thus using puts without #includeing the relevant header, i.e. prepending #include <stdio.h> (or declaring the puts function with int puts(const char*);) is a constraint error.
A constraint error is an error that must cause the compiler output a diagnostics message. Additionally such a program is considered an invalid program. However the peculiar thing about the C standard is that it allows a C compiler to also successfully compile an invalid program, though a compiler may as well reject it. Therefore, such an example is hardly a good starting point in a book that is supposed to teach C to beginners.