I've been trying to implement PIMPL using the g++ compiler on my local CygWin install and I'm beginning to think it may be the fact that I'm running g++ 4.3.4, inasmuch as its C++11 support is less than perfect.
With the very baseline code (from MSDN here):
my_class.h:
#include <memory>
class my_class {
public:
my_class();
private:
class impl; unique_ptr<impl> pimpl(new impl);
};
my_class.cpp:
#include "my_class.h"
class my_class::impl { int my_int; };
my_class::my_class(): pimpl( new impl ) {};
I try to compile with g++ -std=c++0x -o my_class.o my_class.cpp and end up with:
In file included from my_class.cpp:1:
my_class.h:8: error: ISO C++ forbids declaration of 'unique_ptr' with no type
my_class.h:8: error: invalid use of '::'
my_class.h:8: error: expected ';' before '<' token
my_class.cpp: In constructor 'my_class::my_class()':
my_class.cpp:5: error: class 'my_class' does not have any field named 'pimpl'
I also get that if I substitute -std=gnu++0x.
In fact, when I try to compile even the simplest file, lifted from another SO answer:
#include <iostream>
#include <memory>
int main() {
std::unique_ptr<int> up( new int( 30 ) );
}
it complains that unique_ptr is not in the std namespace.
The gcc c++11 support page has no entry for unique_ptr but, from looking at the net, it's been around for quite a while, at least since 4.4.
So my question is, firstly, at what version of gcc was support for unique_ptr added?
And, secondly, am I just making some bonehead mistake in my code, using it the wrong way?
In your first example, the std:: qualifier is missing on unique_ptr. The second example is correct C++11.
According to the GCC 4.4 release notes, unique_ptr was not in GCC's standard C++ library before 4.4:
Improved experimental support for the upcoming ISO C++ standard, C++0x, including:
...
unique_ptr, <algorithm> additions, exception propagation, and support for the new character types in <string> and <limits>.
Related
I am trying to make the following code work on both Linux and FreeBSD based system, Is it a valid usage of macros __GLIBC__ and __USE_XOPEN2K8?
#include <stdio.h>
#include <langinfo.h>
#include <locale.h>
#include <xlocale.h>
int main(void) {
//#if defined(__GLIBC__) && defined (__USE_XOPEN2K8)
locale_t loc;
char *locale_messages = "en-US.utf-8";
loc = newlocale(LC_ALL_MASK, locale_messages, (locale_t)0);
if (loc != NULL)
{
char result[256];
sprintf(result, "%s_%s.%s",
nl_langinfo_l(_NL_IDENTIFICATION_LANGUAGE, loc),
nl_langinfo_l(_NL_IDENTIFICATION_TERRITORY, loc),
nl_langinfo_l(CODESET, loc));
}
//#endif
}
If I don't use those directives, I get the following error on mac OS. I want to disable that code to avoid the following errors.
error: use of undeclared identifier '_NL_IDENTIFICATION_LANGUAGE'
nl_langinfo_l(_NL_IDENTIFICATION_LANGUAGE, loc),
^
error: use of undeclared identifier '_NL_IDENTIFICATION_TERRITORY'
nl_langinfo_l(_NL_IDENTIFICATION_TERRITORY, loc),
I have found one thread recommending use _GNU_SOURCE and _XOPEN_SOURCE, but as result above code is disabled on my linux system too. It seems I need to define _GNU_SOURCE before using it, but before proceding with this idea, can we work with __GLIBC__ and __USE_XOPEN2K8.
You can use
#indef __FreeBSD__
#endif
preprocessor directives to ignore the code that shouldn't be built on FreeBSD. However man nl_langinfo_l on FreeBSD says that this function is present on FreeBSD, so you shouldn't have any problems with it.
The best way is to use a build system to detect if that option is available and then conditionally enable that part of code depending of the detection result. This is how autotools project came to be - to detect differences between operating systems.
In cmake you could:
include(CheckCSourceCompiles)
check_c_source_compiles("
#define _GNU_SOURCE
#define _SOMETHING_READ_FEATURE_TEST_MACROS
#include <something something that is needed.h>
int main() { return _NL_IDENTIFICATION_TERRITORY; }
" WE_HAVE_NL_IDENTIFICATION_TERRITORY)
if(WE_HAVE_NL_IDENTIFICATION_TERRITORY)
target_add_definitions(your_target PUBLIC LIB_HAS_NL_IDENTIFICATION_TERRITORY)
endif()
and then use your own LIB_HAS_NL_IDENTIFICATION_TERRITORY macro that detect if that option is available or not. Such solution is stable, easy to port and dynamically reacts to environment changes.
I am building gcc 9.10 and it works great with c threads but im doing something wrong with g++ and libstdc++-v3 I just dont know what.
I compile gcc/g++, glibc, and libstdc++-v3
I see that the file at include/c++/9.1.0/threads
When I go to compile a simple test program I get
error: ‘thread’ is not a member of ‘std’
C pthread test program compiles
#include <pthread.h>
int main(){
tpthread_t t;
}
C test program compiles
#include <threads.h>
int main(){
thrd_t t;
}
Cxx test program does not compile
#include <thread>
int main(){
std::thread t;
}
Gets error
error: ‘thread’ is not a member of ‘std’
Looking into the header include/c++/9.1.0/threads
#if defined(_GLIBCXX_HAS_GTHREADS)
it looks like it skips everything if that is not defined
how can I check to see if thats the case and then why?
I made this little test and it compiles indicating to me that _GLIBCXX_HAS_GTHREADS is not defined
int main(){
#if defined(_GLIBCXX_HAS_GTHREADS)
123 here error
#endif
}
when compiling libstdc++-v3 I use
../libstdc++-v3/configure -v --enable-libstdcxx-threads=yes
even though I would think threads should be enabled by default on a linux x64 system
The other question doesnt help my situation it was from a long time ago and gcc has changed. One comment looks like it touches on my issue but doesnt go any deeper
If you look in the thread header, it appears that the class only exists #if defined(_GLIBCXX_HAS_GTHREADS) && defined(_GLIBCXX_USE_C99_STDINT_TR1). I'm not sure though, what you'd have to do to have those defined
Thats the issue im having but theres no solution
The answer was to configure with --enable-threads=yes I dont know why that was so hard to find and why thats not default
I am using an extensive piece of code which compiles in Windows and Linux with gcc>=4.7. It is a utility to seamlessly generate mex functions in Matlab from m-scripts written by someone. I am having trouble compiling a short c script (not provided here) in Mac os x. I am using gcc-4.8 with C++11. It uses Boost library only for headers. The piece of utility code where it gets stuck is:
/* gets mxClassID, given C type>
eg. mx_class_id<float>()*/
template<typename T>
struct mx_class_id
{
operator mxClassID()
{
return static_cast<mxClassID>(boost::mpl::at<mxInverseTypeMap,T>::type::value);
}
};
required by
template<typename T>
mxArray* mxCreateScalar(const T & val)
{
//mxClassID cid=static_cast<mxClassID>(boost::mpl::at<mxInverseTypeMap,T>::type::value);
mxArray * arr=mxCreateNumericMatrix(1,1,mx_class_id<T>(),mxREAL);
mxSetValue(arr,val);
return arr;
}
What am I missing? Is it conflicting with built-in clang libraries? Or is it a header not specified (boost/mpl/at.hpp is included)? As I mention it does compile in Matlab for Windows and Linux.I have tried boost 1.51.0 (this is what we use) and also 1.56.0 (this is what Matlab uses) but I get the same error message.
The code I use to compile is
mex -v /usr/local/bin/gcc-4.8 -I path-to-boost-library -I path-to-private-library -I /usr/local/lib -std=C++11 script.cc
Here is the error message I am getting:
error: 'value' is not a member of 'boost::mpl::aux::wrapped_type <
boost::mpl::aux::type_wrapper < mpl_::void_> > ::type {aka
mpl_::void_}'
Any pointers or help appreciated. Thanks
This was resolved by the conflicting use of 'size_t' and 'unsigned long int'.
I think in Linux, Windows, size_t was employed in the code with the assumption it to be uint64_t. And it compiled in both.
However, for mac os x, it is either size_type or unsigned long int. This especially created problem because the code was matching c type to Matlab mex type with one-to-one mapping. In inverse mapping, with the use of size_t this one-to-one mapping was getting lost and instead became many-to-one. Once that was addressed it was easy to fix the rest.
I'm using 64-bit gcc-4.8.2 to generate a 32-bit target, and my machine is 64-bit. I'm using c++11 concurrency features such as thread, mutex, conditiona_variables and etc.
The linker gave the above error message when trying to link the executable. libMyLib is also part of the project.
libMyLib.so: undefined reference to '__gthrw___pthread_key_create(unsigned int*, void (*)(void*))
nm libMyLib.so | grep pthread_key_create shows:
U _ZL28__gthrw___pthread_key_createPjPFvPvE
w __pthread_key_create##GLIBC_2.0
where is the symbol 'ghtrw___pthread_key_create' from? I tried adding '-lpthread(-pthread)' as compiler flag, but it does not help.
More information. nm libMyLib.so | grep pthread shows other symbols such as _ZL20__gthread_mutex_lockP15pthread_mutex_t is defined
where is the symbol 'ghtrw___pthread_key_create' from?
It is defined in GCC's "gthreads" abstraction layer for thread primitives, in the gthr-posix.h header.
#if SUPPORTS_WEAK && GTHREAD_USE_WEAK
# ifndef __gthrw_pragma
# define __gthrw_pragma(pragma)
# endif
# define __gthrw2(name,name2,type) \
static __typeof(type) name __attribute__ ((__weakref__(#name2))); \
__gthrw_pragma(weak type)
# define __gthrw_(name) __gthrw_ ## name
#else
# define __gthrw2(name,name2,type)
# define __gthrw_(name) name
#endif
/* Typically, __gthrw_foo is a weak reference to symbol foo. */
#define __gthrw(name) __gthrw2(__gthrw_ ## name,name,name)
...
#ifdef __GLIBC__
__gthrw2(__gthrw_(__pthread_key_create),
__pthread_key_create,
pthread_key_create)
After preprocessing that expands to:
static __typeof(pthread_key_create) __gthrw___pthread_key_create __attribute__ ((__weakref__("__pthread_key_create")));
It is supposed to be a weak reference to __pthread_key_create, so it should never have a definition, because it is just a reference to glibc's internal __pthread_key_create symbol.
So it looks like something has gone wrong with how you build you library. You should not have an undefined weak symbol.
I recently stumbled into this error, and not because of a missing -pthread.
The situation happened in a somewhat unusual setup: I was compiling a software written in C++14 under Centos7. Since C++14 requires a recent version of GCC, I relied on devtoolset 6 for it.
Given the specific setup, I opened a thread on the Centos mailing list, so I'm directly referencing the relevant thread. See https://lists.centos.org/pipermail/centos-devel/2018-May/016701.html and https://lists.centos.org/pipermail/centos-devel/2018-June/016727.html
In short, it might be caused by some bug in the preprocessor macros, either of glibc or libgcc. It can be fixed by placing #include <thread> in the beginning of the source code which gives problems once compiled. Yes, even if you don't use std::thread in it.
I don't claim this will work for everyone, but it might do the job in some particular situations.
I'm not able to compile clang(3.3) using MinGW 4.8.1. The following error always pops-up when 70% build is complete:
clang/lib/Basic/FileManager.cpp includes sys/stat.h, which defines #define stat _stat64i32 (actually there are a few other defines in between, but you get the idea ;)
clang/include/clang/Basic/FileManager.h does not include sys/stat.h; instead only has a forward-declaration.
Hence, while parsing the header, the forward declaration is used (struct stat)
But when it finally arrives at the implementation, the preprocessor will kick in and replace struct stat with struct stat64i32. Hence the mismatch.
The best solution would be to change the forward declaration in the header to instead include sys/stat.h. (I didn't actually test if it will compile then)
The current trunk does not contain the code anymore.
Update: regarding off64_t. This is defined in _mingw_off_t.h these days as:
#ifndef _OFF64_T_DEFINED
#define _OFF64_T_DEFINED
__MINGW_EXTENSION typedef long long _off64_t;
#if !defined(NO_OLDNAMES) || defined(_POSIX)
__MINGW_EXTENSION typedef long long off64_t;
#endif
#endif /*_OFF64_T_DEFINED */
So you probably want to define _POSIX before including io.h (or stdio.h)