Bug in clang thread_local initialization - c++

The following code should be creating the in-class thread_local only once, but it ends up initializing it on every access
#include <iostream>
#include <thread>
using std::cout;
using std::endl;
template <typename T>
class Something {
public:
struct TLBookkeeping {
TLBookkeeping() {
std::cout << "TLBookkeeping() " << std::this_thread::get_id() << std::endl;
}
};
static void foo();
static thread_local TLBookkeeping bookkeeping_;
};
template <typename T>
thread_local typename Something<T>::TLBookkeeping Something<T>::bookkeeping_;
template <typename T>
void Something<T>::foo() {
std::cout << &bookkeeping_ << std::endl;
std::cout << &bookkeeping_ << std::endl;
}
namespace {
struct Struct {};
}
int main() {
Something<Struct>::foo();
}
(https://wandbox.org/permlink/fgqCDHV0axKDRt89)
Interestingly the bug only shows when Struct is in an anonymous namespace.
Does someone know if this is a clang bug (gcc does it right - https://wandbox.org/permlink/hsxRj8OdYbt4Eeck) or an inherently incorrect usage of thread_local? If the latter, what is the correct usage? If the former, what exactly is the bug? And is this documented somewhere? Should we open a bug report?

When you find that a compiler causes runtime behavior which you are relatively certain is incorrect; and another popular compiler does not cause that same behavior - that is sufficient, IMHO, in order to file a bug against said compiler.
As #SamVarshavchik suggestions, you:
Visit LLVM's bug tracker
Create an account if you don't have one
Look for duplicates (e.g. using the term "thread-local")
If you don't find one - you file a bug
I've done just that, so now we have bug 42111.
At worst - it'll be marked as a dupe.
edit: It was not a dupe, and has just now (June 5th 2019) been fixed.

Related

C++17 static and constexpr

I'm using the clang that comes bundled with Xcode 9.3, and I'm trying to understand whether the following result is an intentional part of C++17 changes:
#include <iostream>
template<typename T> struct Test {
static const int TEN;
};
template<typename T> constexpr int Test<T>::TEN = 10;
int main(int argc, const char * argv[]) {
std::cout << Test<int>::TEN << std::endl;
return 0;
}
When compiled with c++11 or c++14, this prints "10".
However, compiling this with c++17, this prints "0".
What's going on?
After posting this elsewhere, a clang developer acknowledged that this was a bug in clang-5 c++17 implementation, and that it is fixed in clang-6 onwards.
Thanks to tkausl for his initial comment that showed differing results in clang-6 and gcc, which led me to ask elsewhere.

A "nicer" alternative to prefixing local variable names?

In a bunch of code that I'm writing I want to indicate that certain variables are to be used in a certain way, or have a certain characteristic to them. For the sake of discussion, suppose variables can be sweet, salty, sour or bitter.
What I use now is something like:
int foo() {
int salty_x;
int sour_y;
do_stuff_with(salty_x,sour_y);
}
And I might also have sour_x, or salty_y etc.
Ideally - but this is not valid C++ - I would have been able to write something like this:
int foo() {
namespace salty { int x; }
namespace sour { int y; }
do_stuff_with(salty::x,sour::y);
}
and this would nicely allow for a "sour x" and a "salty x" in the same function - if this syntax had been valid of course.
This may remind you of Hungarian Notation, except that it's not about variable types or sizes, and that the saltiness or sourness etc. are not inherent in x or in y - they only describe the way they're used.
Now, you could ask: "Ok, why not just put these in struct's?", that is, why not do:
int foo() {
struct { int x; } salty;
struct { int y; } sour;
do_stuff_with(salty.x,sour.y);
}
But that preculdes defining additional salty/sour variables; and if I bunch them all at the beginning of the function, C-style, then it looks as though I indicate the variables are related, which is not necessarily the case.
What I currently do is just prefix the names: salty_x, sour_y. It's ugly but it works.
My question: Is there something else I could do which would look closer, in use, to my desired code, and at the same time not require too much "coding gymnastics"?
Due to popular demand: As a motivating/concretizing example, "salty" might mean "is uniform across all threads in a GPU warp, but possibly not across different warps" and "sour" might mean "is uniform across all threads in a CUDA kernel grid block / OpenCL workgroup when they reach this point in the code". But this is not a question about GPUs, CUDA, or OpenCL.
The hardest constraint was
Sometimes I even want to have a "sour x" and a "salty x" in the same
function
So - the solution is the first usage of variadic template template parameter I ever made - so, here you are:
template <typename T>
struct salty
{
T salty;
};
template <typename T>
struct sour
{
T sour;
};
template <typename T, template <typename> class ...D>
struct variable : D<T>...
{};
And the usage:
salty<int> x;
x.salty = 5;
variable<int, salty, sour> y;
y.sour = 6;
y.salty = 5;
I'm sure you've checked all conventional approaches and neither was satisfactory... Lets turn to the magic then to achieve (I think) exactly what you want (c++17 will be needed):
#include <iostream>
#include <type_traits>
#include <variant>
#include <utility>
#include <typeinfo>
#include <typeindex>
#include <map>
template <auto Label>
using ic = std::integral_constant<decltype(Label), Label>;
template <class... Ts>
struct context {
template <auto Label, auto (*Namespace)(std::integral_constant<decltype(Label), Label>)>
decltype(Namespace(ic<Label>{}))& get() {
try {
return std::get<decltype(Namespace(std::integral_constant<decltype(Label), Label>{}))>(values[typeid(std::pair<std::integral_constant<decltype(Namespace), Namespace>, std::integral_constant<decltype(Label), Label>>)]);
} catch (std::bad_variant_access&) {
values[typeid(std::pair<std::integral_constant<decltype(Namespace), Namespace>, std::integral_constant<decltype(Label), Label>>)] = decltype(Namespace(std::integral_constant<decltype(Label), Label>{})){};
}
return std::get<decltype(Namespace(std::integral_constant<decltype(Label), Label>{}))>(values[typeid(std::pair<std::integral_constant<decltype(Namespace), Namespace>, std::integral_constant<decltype(Label), Label>>)]);
}
std::map<std::type_index, std::variant<Ts...>> values;
};
int main(){
enum { x }; // defining label x
int salty(ic<x>); // x is an int in salty namespace
enum { y }; // defining label y
float sour(ic<y>); // y is a float in sour namespace
context<int, float, char> c;
c.get<x, salty>() = 2;
c.get<y, sour>() = 3.0f;
char sour(ic<x>); // x is a char in sour namespace
c.get<x, sour>() = 'a';
std::cout << "salty::x = " << c.get<x, salty>() << std::endl;
std::cout << "sour::y = " << c.get<y, sour>() << std::endl;
std::cout << "sour::x = " << c.get<x, sour>() << std::endl;
}
One thing to be mentioned - gcc doesn't like the code though according to standard it should: [see this] [and that].
If I understand your edit correctly, you want to be able to define variables that behave exactly like int or float variables, but retain additional, ideally compile-time, information about their types.
The only thing I can't help you with is this:
Sometimes I even want to have a "sour x" and a "salty x" in the same function, which I could do if this syntax had been valid.
Personally, I would just prefix the variable name.
Anyway, here is an example of what you can do.
enum class Flavor {
Salty, Sour
};
template <typename T, Flavor f>
struct Flavored {
using Type = T;
static constexpr Flavor flavor = f;
T value;
Flavored(T v) : value(v) {}
operator T() { return value; }
};
And here is an example of how to use it.
Postfixes.
They usually hamper readibility a lot less than prefixes, while maintaining the same hinting quality.
Yes I know it's obvious, but it's very possible that it hadn't come to your mind.
And mind that the Hungarian Notation was originally meant to be employed pretty much as you would in your case; see "Apps Hungarian" in that wikipedia entry.

How do I write template code that handles type conversion for strings?

I was trying to make a simple function that allowed checking if a string was in a given list.
Here is some demo code:
#include <string>
#include <iostream>
#include <set>
#include <initializer_list>
template<typename T2, typename T>
bool contains(T const& value, std::initializer_list<T2> const& set)
{
return std::find(std::begin(set), std::end(set), value) != std::end(set);
}
int main(void)
{
std::set<std::wstring> values = { L"bar", L"not" };
for (std::wstring val : values) {
std::wcout << "\"" << val << "\" ";
if (contains(val, { L"foo", L"bar", L"baz", L"doom" })) {
std::wcout << "found" << std::endl;
}
else {
std::wcout << "not found" << std::endl;
}
}
}
As you can see I am trying to check if a std::wstring is in a list of const wchar_t*consts.
This compiles with the MS compiler (and seems to work) but GCC complains that no types to make it work can be derived. Interestingly it also doesn't compile with the MS compiler anymore if I switch the order of the template parameters so the 6th line reads:
template<typename T, typename T2>
In that case the compiler says T is ambiguous.
I've tried a few variations like using only one template parameter but then I can't call it with strings and pointers anymore.
How do I do this - if possible - properly?
Your code compiles in GCC 4.8.1 with the addition of:
#include <algorithm>
std::find is declared in <algorithm>. The C++ Standard Library that ships with MSVC often brings in seemingly unnecessary headers. I'm betting is tagging along with <set> or <initializer_list>.
A working example can be found here.
You're grabbing a wrong overload of find (best effort - the compiler can't find the intended one), you need to include
#include <algorithm>
This is also true for gcc 4.9.0

Why this C++ recursive template didn't work?

I found interesting question and decided to examine top answer in detail.
I asked myself why there needs structure and try to rewrote the code without it:
#include <iostream>
template <int N> void out(std::ostream& os) {
out<N-1>(os);
os << N << std::endl;
}
template <> void out<1>(std::ostream& os){
os << 1 << std::endl;
}
int main(){
out<100>(std::cout);
}
And then I tried to refactor the code.
I got something like this:
#include <iostream>
template <int N> void out() {
if (N != 1) {
out<N-1>();
std::cout << N << std::endl;
}
else {
std::cout << 1 << std::endl;
}
}
int main(){
out<100>();
}
I don't understand why this code didn't work.
Any ideas?
The problem is that the if condition is evaluated at run-time. When you get to the instantiation where N = 1, it doesn't know that the first block of the if statement won't execute. It proceeds to instantiate out<0> and so on. If we had a static if, this would be possible, but it probably won't happen very soon.
Templates are expanded during compilation while if statements are only checked during run-time which is a different later stage. In your case the compiler will try to expand indefinetely as there is no specific implementation of the function for a fixed value of N(that used to be 1).

Weird behaviour of Koenig Lookup

consider the following program:
namespace NS2 {
class base { };
template<typename T>
int size(T& t) {
std::cout << "size NS2 called!" << std::endl;
return sizeof(t);
}
};
namespace NS1 {
class X : NS2::base { };
}
namespace NS3 {
template<typename T>
int size(T& t) {
std::cout << "size NS3 called!" << std::endl;
return sizeof(t) + 1;
}
template<typename T>
class tmpl
{
public:
void operator()() { size(*this); }
};
};
int main() +{
NS3::tmpl<NS1::X> t;
t();
return 0;
}
My compiler (gcc 4.3.3) does not compile the program because the call to size is ambigous. The namespace NS2 seems to be added to the set of associate namespaces for the size call in the class tmpl. Even after reading the section about Koenig Lookup in the ISI Standard I am not sure if this behaviour is standard conform. Is it?
Does any one know a way to work around this behaviour without qualifying the size call with the NS3 prefix?
Thanks in advance!
Template arguments and base classes both affect ADL, so I think GCC is correct, here: NS3 comes from the current scope, NS1 from the X template argument, and NS2 from the base class of the template argument.
You have to disambiguate somehow; I'd suggest renaming one or more of the functions, if feasible, or perhaps use SFINAE to disambiguate the functions.
(Similar Situation: Note that boost::noncopyable is actually "typedef noncopyable_::noncopyable noncopyable;" so that the boost namespace doesn't get added to the ADL set of types that derive from it.)