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.
Related
Due to specific IO process on ibm i there's requirement of using display file fields IO.
As follows we need compile time structures for display file values.
After looking at constexpr I've decided to try some cpp + templates solution from here.
The final code for my case looks like this:
MYSRC/MYMOD.CPP
#include "MYSRC/MODINCH"
template <int N>
constexpr_string<N> make_constexpr_string(const char(&a)[N]) {
// Provide a function template to deduce N ^ right here
return constexpr_string<N>(a);
// ^ Forward the parameter to the class template.
};
int main(int argc, char** argv)
{
return 0;
}
MYSRC/MODINCH.H
#include <algorithm>
#define __IBMCPP_TR1__ 1
#include <QSYSINC/STD(array)>
using std::size_t;
template <size_t N> // N is the capacity of my string.
class constexpr_string {
private:
//std::tr1::array<char, N> data_; // Reserve N chars to store anything.
char data_[N];
std::size_t size_; // The actual size of the string.
public:
constexpr constexpr_string(const char(&a)[N]): data_{}, size_(N - 1)
{
for (std::size_t i = 0; i < N; ++i) {
data_[i] = a[i];
}
}
constexpr iterator begin() { return data_; } // Points at the beggining of the storage.
constexpr iterator end() { return data_ + size_; } // Points at the end of the stored string.
};
The code above compiles with
CRTCPPMOD MODULE(QTEMP/MYMOD) SRCFILE(MYLIB/MYSRC) SRCMBR(MYMOD)
OPTIMIZE(40) DBGVIEW(*ALL) LANGLVL(*EXTENDED0X)
for both char data_[N]; and std::tr1::array<char, N> data_;
However, when I try to populate instance of constexpr_string like this:
#include "MYSRC/MODINCH"
template <int N>
constexpr_string<N> make_constexpr_string(const char(&a)[N]) {
// Provide a function template to deduce N ^ right here
return constexpr_string<N>(a);
// ^ Forward the parameter to the class template.
};
int main(int argc, char** argv)
{
auto test1 = make_constexpr_string("blabla");
constexpr_string<7> test("blabla");
return 0;
}
error instantly fails compilation with this message
CZP0063(30) The text "constexpr_string" is unexpected. right at the ctor line. For me this looks like compiler can not determine the constexpr keyword in this situation, but why?
Did I messed somewhere in code or this usage just currently unsupported?
Here is the supported features of ibm compiler and the IBM XLC++ supports constexpr as far, as I can deduct from given table.
Given this is tagged as ibm-midrange, I'm not sure the feature set of IBM XLC++ is the proper reference to use. I think you want to be using this instead. In particular if you want to use C++0x features (which are not yet fully supported), you need to compile using LANGLVL(*EXTENDED0X).
For further information, this link shows information on support for ILE C++0x language extensions.
I can't verify this on the ibm-midrange system because I don't have access to the CPP compiler there but I think I've found your issue:
#include "MYSRC/MODINCH"
template <int N>
constexpr_string<N> make_constexpr_string; // <------ You are missing this semicolon
...
int main(int argc, char** argv)
{
auto test1 = make_constexpr_string("blabla");
constexpr_string<7> test("blabla");
return 0;
}
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.
Here I've implemented a templated function and a templated Lambda. I've started exploring C++14 features and not sure what's wrong with the following lambda. Any suggestions?
#include <iostream>
#include <random>
#include <algorithm>
#include <functional>
template<class T = std::mt19937, std::size_t N = T::state_size>
auto MersenneEngine() {
return T(N);
}
template<class T = std::mt19937, std::size_t N = T::state_size>
auto MersenneEngineLambda = []() {
return T(N);
};
int main() {
// your code goes here
std::cout << MersenneEngine<std::mt19937>() << std::endl;
std::cout << MersenneEngineLambda<std::mt19937>() << std::endl; // Compilation error : error: use of 'MersenneEngineLambda<std::mersenne_twister_engine...before deduction of 'auto'
return 0;
}
Here's the complete code http://ideone.com/lveJRN
The code is fine.
You are witnessing a bug in your version of GCC (5.1). This is not highly surprising given that variable templates were brand new in GCC 5.
Empirically, it was fixed either in or before GCC 6.1.1.
Bug 67041 (and, more directly, its dupe bug 67350) looks potentially relevant.
Is it normal that this compiles fine?
#include <vector>
#include <algorithm>
int main()
{
std::vector<int> buf;
generate(buf.begin(), buf.end(), []{ return 0; });
}
(Note the missing std:: in front of generate())
Is this behavior documented somewhere? Or did I stumble across a compiler or library bug? Which in my case would be GCC 5.3.0 and Clang 3.8.0 on Linux; both use libstdc++, so maybe library bug?
This is allowed, essentially because the arguments to generate are in std.
Code like
namespace Foo
{
struct B{};
void foo(const B&);
}
int main()
{
Foo::B b; /*Requires Foo::*/
foo(b); /*Does not require Foo:: as that is gleaned from the argument*/
}
is acceptable for similar reasons. We call it argument dependent lookup. See https://en.wikipedia.org/wiki/Argument-dependent_name_lookup
Hi when running the following using gcc 4.8.1 when using the thread_local keyword the assertion is hit. When removing the thread_local the assert is not hit. Does anyone know why this is? There is some undefined global ordering but I would expect buf_ to have a valid address before assigning ptr_. Just remove the keyword thread_local and it works for me.
Output:
$ ./ThreadLocal
Running Tester
ThreadLocal: main.cpp:13: int main(): Assertion `buf == ptr' failed.
Aborted (core dumped)
Output when removing thread_local keyword
Running Tester
Test.hpp
#include <iostream>
#include <cassert>
template <typename std::size_t N>
struct Mem
{
Mem() noexcept: ptr_(buf_)
{}
char * getBuf() { return buf_; }
char * getPtr() { return ptr_; }
private:
char buf_[N];
char * ptr_;
};
template <typename std::size_t N>
struct Tester
{
Tester()
{
std::cout << " Running Tester " << std::endl;
}
char * getPtr() { return _mem.getPtr(); }
char * getBuf() { return _mem.getBuf(); }
private:
static thread_local Mem<N> _mem;
};
main.cpp
#include <iostream>
#include "Test.hpp"
template <typename std::size_t N>
thread_local Mem<N> Tester<N>::_mem;
int main()
{
Tester<500> t;
char * ptr = t.getPtr();
char * buf = t.getBuf();
assert( buf == ptr );
}
It looks like a bug in GCC. Apparently Tester::_mem is not being initialized at all. GCC 4.9.0 does the same, but clang 3.5.0 works fine
Making _mem not dependent on template parameter makes GCC crash.
Finally, making Tester a non-template class makes GCC work at last.
Update: These seem to be known bugs in GCC.