Mac gcc doesn't allow calling std::string::~string explicitly - c++

strdata->std::string::~string();
Here is the error I get:
error: '~' in destructor name should be after nested name specifier
strdata->std::string::~string();
^
I am using a cmake project... My gcc version installed via brew is following:
gcc --version
Configured with: --prefix=/Library/Developer/CommandLineTools/usr --with-gxx-include-dir=/usr/include/c++/4.2.1
Apple LLVM version 7.0.2 (clang-700.1.81)
Target: x86_64-apple-darwin15.2.0
Thread model: posix
I couldn't find the ~string() defined anywhere in the header files. I ended up changing it as follows and that works. It is ok for my use case for now.
strdata->std::string::~basic_string();
This original seems correct and works perfectly in GCC on Linux and CYGWIN. What is the issue which is preventing it from working on mac? Templates? Something else?

This isn't a complete answer. For some reason, using namespace std; works, but without that clang fails. Consider this example:
#include <new>
#include <type_traits>
namespace foo {
struct A {};
typedef A A_t;
}
int main() {
std::aligned_storage<sizeof(foo::A)>::type storage;
foo::A_t* obj = new(&storage) foo::A;
using namespace foo; // Without this line, clang fails.
obj->foo::A_t::~A_t();
}
Without the using namespace foo; line, clang will give an error expected the class name after '~' to name a destructor. But with that line, it works. Extending this to std::string:
#include <new>
#include <type_traits>
#include <string>
int main() {
std::aligned_storage<sizeof(std::string)>::type storage;
std::string* obj = new(&storage) std::string;
using namespace std; // Without this line, clang fails.
obj->std::string::~string();
}
it works. It also works with the narrower using std::string;.
This doesn't answer the question of why clang fails. I don't know if it's a bug in clang or in gcc. But at least a workaround exists.
It may be worth reporting this as a bug in clang, and then letting them decide whether or not it really is a bug.

Related

Why is charconv header missing in macosx Mojave 10.14 with gcc5?

I am trying to do some very fast conversions in C++ and charconv seems the way to go since it uses a very low level logic. The problem is that when I try to include this header and then call, say, std::to_chars(...), neither the header is found nor std has a 'to_chars' member. I updated and reinstalled gcc but this problem is still there. Now I have seen some threads that say that I should update somehow libc++17 but they are not very specific about what I should do, as things are a bit different for MacOS.
Some code to illustrate the library and it's use:
#include <iostream>
#include <typeinfo>
#include <charconv> //error: 'charconv' file not found
struct to_chars_result{
char *str;
std::errc err;
};
int main(int argc, const char * argv[]) {
std::string str("12Test");
auto result = std::to_chars(str.data(), str.data()+str.size(), 12345); //No
//member named 'to_chars' in namespace 'std'.
return 0;
}
As for gcc -v command output:
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/usr/local/libexec/gcc/x86_64-apple-darwin14.4.0/5.1.0/lto-
wrapper
Ziel: x86_64-apple-darwin14.4.0
Konfiguriert mit: ../gcc-5.1.0/configure --enable-languages=c++,fortran
Thread-Modell: posix
gcc-Version 5.1.0 (GCC)
Any help appreciated!
gcc 5.1 was released on April 22, 2015.
The paper that added to_chars to the C++17 standard was written in 2016.
Why do you expect that gcc5 will have implemented it?
[ Later: That was the paper that added the <charconv> header, too ]

Error using alias declaration

I'm trying to compile an easy program that use the alias declaration.
This is the code:
#include <iostream>
using namespace std;
using in = int;
in main ()
{
in a = 1;
cout << a << '\n';
return 0;
}
The command I use to compile is g++ -std=c++0x program_name.cxx, using the built-in terminal in Kate on Ubuntu OS.
But it doesn't work! Any suggestion?
(instead using typedef int in; it works).
Compile in C++11 mode. Type aliasing is supported only in C++11. I suspect the g++ version that use is older and doesn't fully support c++11, hence fails with c++0x.
Compile with: g++ -std=c++11 file.cpp
and it works.
By the way, it seems to be a terrible idea to alias int in such a way.

c++ error std::result_of does not name a type

After g++ -std=c++0x'ing std::result_of produces the following error message
error: ‘result_of’ in namespace ‘std’ does not name a type
(g++ version 4.5.0 on SUSE.)
The relevant piece of code, sufficient for reproducing the error is below
#include <random>
#include <type_traits>
using namespace std;
class Rnd{
protected:
static default_random_engine generator_;
};
template<class distribution>
class Distr: Rnd{
distribution distribution_;
public:
typename std::result_of<distribution(default_random_engine)>::type
operator() (){ return distribution_(default_random_engine); }
};
Moreover, I have tried to compile examples from wikipedia or cpluplus.com to no avail.
Is it a problem with the particular compiler or am I doing something wrong?
Try to include <functional> also. gcc 4.5 is based on an older version of C++11, in which std::result_of is defined in <functional> instead of <type_traits>.
This move was introduced in n3090 (2010 March 29) after fixing issue 1270. gcc 4.5.0 was released just 16 days after the change (2010 April 14), which did not have enough time to apply, as we can see from this online source code of <functional>.
std::result_of was moved to <type_traits> in gcc 4.6.

c++ mingw STL installation

I recently installed MinGW and MSYS on my Windows 32 machine and it seems to be running fine.
On the C++ compiler, I am including a vector container and getting no errors to that. But I`m getting compile-time errors when I try to use it.
So, the code
#include <vector> // include vector.h
#include <stdio.h> // include stdio.h
using namespace std;
main() {
// vector<int> A;
printf("\nHeya ..");
}
is running just fine. However, the moment I un-comment line 8-- the vector declaration line, I get the following error (shortened) in compile time:
undefined reference to 'operator delete(void*)'
undefined reference to '__gxx_personality_v0'
You're probably compiling with gcc instead of g++. The actual compiler is the same, but g++ tells the linker to use the default C++ libraries, were gcc only tells it to look at the C libraries. As soon as you use and C++-specific parts of the standard library, gcc will fail.
As an aside, C++ doesn't support the default int rule from old C, so you should really specify the return type from main.
I don't see how you are compiling your code. Your main method is invalid, incorrect signature and you aren't returning anything.
Should be like this:
#include <vector> // include vector.h
#include <stdio.h> // include stdio.h
using namespace std;
int main(int, char**) {
// vector<int> A;
printf("\nHeya ..");
return 0;
}
Also you need to compile this with g++ and not gcc.

Is std::ofstream movable?

I have this map which compiles fine in MSVC10 :
std::map<std::string, std::ofstream> m_logFiles;
But on ubuntu using g++ 4.5 with C++0x enabled, I get the following error message :
/usr/include/c++/4.5/bits/ios_base.h|785|error: ‘std::ios_base::ios_base(const std::ios_base&)’ is private
By using pointers instead of objects, I resolved the problem.
Searching on the web, I learned that streams are not meant to be copied (the why was well explained). But my question is, is std::ofstream a movable type ? If it is, shouldn't it allow its use as a template parameter in the standard containers ?
If yes, then is g++ behind MSVC10 on this point ? (which would explain why it works on MSVC). I know it would be silly to ask compiler writers to fully implement something that isn't even final, but I'm curious regarding the future.
Using g++ 4.6.1 didn't help.
Edit : reading the comments I dug a little bit further and found that the insert is causing the problem, not the declaration of the map.
Reading Cubbi's link I tried the following :
#include <string>
#include <fstream>
#include <map>
using namespace std;
int main()
{
map<string, ofstream> m_logFiles;
ofstream st;
m_logFiles.insert(make_pair<string, ofstream>(string("a"), move(st)));
return 0;
}
But still no luck. g++ complains about the use of b deleted copy constructor.
std::ofstream is movable. This program compiles for me using clang/libc++:
#include <string>
#include <fstream>
#include <map>
int main()
{
std::map<std::string, std::ofstream> m_logFiles;
}
Reference 27.9.1.11 [ofstream.cons].
I asked a similar question earlier, and later found that GCC doesn't seem to support movable fstreams yet (I just tested GCC 4.6.1) as detailed in this answer.