g++ not destructing thread locals - c++

On my machine, GCC is not calling the destructors of thread_locals.
The code runs fine on clang 7 and Visual Studio.
Is this a bug?
I'm using MinGW GCC 8.1 on Windows.
Thread model: posix
gcc version 8.1.0 (x86_64-posix-seh-rev0, Built by MinGW-W64 project)
Here's the code:
#include <iostream>
struct A {
A() {
std::cout << "A()\n";
}
~A() {
std::cout << "~A()\n";
}
void
print() {
std::cout << "A\n";
}
};
thread_local A a;
int
main() {
a.print();
return 0;
}

Related

Why is gcc not catching an exception from a multi target function?

I'm using the target attribute to generate different function implementations depending on the CPU architecture. If one of the functions throws an exception it doesn't get caught if I compile with gcc, but with clang it works as expected.
If there is only a single implementation of the function it does work for gcc as well.
Is this a bug in gcc?
Example (godbolt):
#include <stdexcept>
#include <iostream>
using namespace std;
__attribute__((target("default")))
void f() {
throw 1;
}
__attribute__((target("sse4.2,bmi")))
void f() {
throw 2;
}
int main()
{
try {
f();
}
catch(... )
{
std::cout << "Caught exception" << std::endl;
}
}
Output of gcc:
terminate called after throwing an instance of 'int'
Output of clang:
Caught exception
I reported this and a GCC developer confirmed it as a bug: link
For now a workaround seems to wrap the function and use the gnu::noipa attribute to disable interprocedural optimizations:
__attribute__((target("default")))
void f() {
throw 1;
}
__attribute__((target("sse4.2")))
void f() {
throw 2;
}
[[gnu::noipa]]
void f1()
{
f();
}
int main()
{
try {
f1();
}
catch(... )
{
return 0;
}
return 1;
}
The bug is now fixed in gcc's master branch and should be released with gcc version 13.

std::destroy_at differences between major compilers?

Using compiler explorer with:
#include <iostream>
#include <memory>
struct test
{
test(int i)
{
std::cout << "test::test("<<i<<")\n";
}
~test()
{
std::cout << "~test()\n";
}
};
template<>
void std::destroy_at(test* p)
{
std::cout<<"std::destroy_at<test>\n";
p->~test();
}
int
main ()
{
auto sp = std::make_shared<test>(3);
return 33;
}
Gives the expected output using C++20 with gcc x86-64 or clang x86-64:
Program returned: 33
test::test(3)
std::destroy_at<test>
~test()
But x64 msvc v19.32 gives:
Program returned: 33
test::test(3)
~test()
As if the std::destroy_at has no effect here.
Is this conforming behavior, my misunderstanding or a msvc non conformance or misconfiguration?
Specializing standard library functions is UB since C++20.

Why is gcc-10 not seeing keywords related to coroutine ts?

I have installed gcc-10 compiler on my ubuntu 20.04. I needed to test the work of coroutine ts, so I found an example using coroutines and tried to compile it.
exemple:
#include <coroutine>
#include <iostream>
struct simple {
static inline int x = 0;
int id = 0;
simple() : id{ x++ } { std::cout << id << " constructed\n"; }
simple(simple&&) : id{ x++ } { std::cout << id << " move constructed\n"; }
~simple() { std::cout << id << " destructed\n"; }
struct promise_type {
simple get_return_object() { return {}; }
void return_void() {}
void unhandled_exception() { std::terminate(); }
auto initial_suspend() noexcept { return std::suspend_never{}; }
auto final_suspend() noexcept { return std::suspend_never{}; }
};
};
simple f() { co_return; }
int main() {
f();
}
Even though I made gcc-10 the default compiler in clion, added the required flag and included the standard 20 in cmake, the compiler still throws an error. Error on the co_return keyword
Std::experimental::coroutine_traits type was not found; include <experimental/coroutine> before defining a coroutine
This is strange because the heading is included without a space, and functions from it are also available.
cmake:
cmake_minimum_required(VERSION 3.17)
project(test6)
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fcoroutines")
add_executable(test6 main.cpp)
How can this gap be resolved?
I use g++ version 10.2.0 and
Package: libstdc++-10-dev-mips64r6-cross
Architecture: all
Version: 10.2.0-5ubuntu1~20.04cross1

error: ‘invoke’ is not a member of ‘std’

Using
g++ (Ubuntu 5.4.0-6ubuntu1~16.04.5) 5.4.0 20160609.
I receive the error
slicing.cpp:31:5: error: ‘invoke’ is not a member of ‘std’
slicing.cpp:32:5: error: ‘invoke’ is not a member of ‘std’
When compiling with
g++ -std=c++17 -O2 -g -Wall -c -o slicing.o slicing.cpp
(and the same with -std=gnu++17) code below, modified from Virtual functions and std::function?.
How can I fix this?
I could not find any useful information.
#include <functional>
#include <iostream>
struct base
{
base() {std::cout << "base::base" << std::endl;}
virtual ~base() {std::cout << "base::~base" << std::endl;}
virtual void operator()() {std::cout << "base::operator()" << std::endl;}
};
struct derived1: base
{
derived1() {std::cout << "derived1::derived1" << std::endl;}
virtual ~derived1() {std::cout << "derived1::~derived1" << std::endl;}
virtual void operator()() {std::cout << "derived1::operator()" << std::endl;}
};
struct derived2: base
{
derived2() {std::cout << "derived2::derived2" << std::endl;}
virtual ~derived2() {std::cout << "derived2::~derived2" << std::endl;}
virtual void operator()() {std::cout << "derived2::operator()" << std::endl;}
};
int main(int argc, char* argv[])
{
base* ptr1 = new derived1();
base* ptr2 = new derived2();
std::function<void()> f1 = *ptr1;
std::function<void()> f2(*ptr2);
std::invoke(*ptr1); // calls derived1::operator()
std::invoke(*ptr2); // calls derived2::operator()
//std::invoke(f1); // calls base::operator()
//std::invoke(f2); // calls base::operator()
delete ptr1;
delete ptr2;
return 0;
}
Use the GCC compiler dialect flag -std=c++1z or even better -std=c++17 and upgrade your compiler to GCC 7.
(ed: your compiler seems a bit old so it may not work; notice that GCC 5 was released before the C++17 standard)
With g++ (x86_64-win32-seh-rev1, Built by MinGW-W64 project) 7.2.0
it builds this correctly
#include <iostream>
// C++17
#include <functional>
int Func(int a, int b)
{
return a + b;
}
struct S
{
void operator() (int a)
{
std::cout << a << '\n';
}
};
int main(/*int argc, char* argv[]*/)
{
using namespace std;
std::cout << std::invoke(Func, 10, 20) << '\n'; // 30
std::invoke(S(), 42); // 42
std::invoke([]() { std::cout << "hello\n"; }); // hello
return 0;
}
source: https://www.viva64.com/en/b/0533/#ID0EOHKO

Crash when std::function is constructed from lambda returned value in VS 2012

This C++ code compiles successfully with VS 2012 but crashes at runtime:
#include <iostream>
#include <functional>
void f()
{
std::cout << "f called" << std::endl;
}
int main()
{
auto get_f= []()
{
bool b = true;
return b ? f : f;
};
std::function<void()> filter(get_f()); // crash here!!!
return 0;
}
If we change get_f to this:
auto get_f= []()
{
return f;
};
then program runs without crashes.
Is it a problem with this code or compiler/std library bug?
I have not tested with newer versions of Visual Studio.
It looks to me like a problem with the standard library (or possibly compiler).
With VS 2013, it compiles and runs without a problem. If we add code to invoke the filter that runs as well:
#include <iostream>
#include <functional>
void f()
{
std::cout << "f called" << std::endl;
}
int main()
{
auto get_f= []()
{
bool b = true;
return b ? f : f;
};
std::function<void()> filter(get_f()); // crash here!!!
filter();
return 0;
}
Output: f called