I am unable to access any functions of TBB's atomic types (fetch/load/etc.). When I look at 'tbb/atomic.h' there are errors at every instance of the macro: '__TBB_DECL_ATOMIC( ... )'
error: 'pure specifier ( = 0 ) allowed only on virtual functions'
On the contrary, everything can be accessed and compiles fine using the MSVC compiler.
This is using the latest version of the Intel C++ compiler, latest version of TBB, 64-bit OS, 64-bit build. Even looking at the macro's code I can't tell where this is coming from. Am I missing a compiler flag or something?
#define __TBB_DECL_ATOMIC(T) \
template<> struct atomic<T>: internal::atomic_impl_with_arithmetic<T,T,char> { \
atomic() = default; \
constexpr atomic(T arg): internal::atomic_impl_with_arithmetic<T,T,char>(arg) {} \
\
T operator=( T rhs ) {return store_with_release(rhs);} \
atomic<T>& operator=( const atomic<T>& rhs ) {store_with_release(rhs); return *this;} \
};
Found the issue. The compiler compiles it just fine, but the environment (VS2012) isn't recognizing the C++11 so I'm not getting Intellisense and I am getting false error squiggles.
Related
I'm using the protoc-3.18.0-win32 version from here. After successfully compiling the .proto files, I get the following error in my QtCreator 5 (C++11) program:
C:\Users\MyName\MyProject\lib\include\google\protobuf\stubs\mutex.h:124: error: temporary of non-literal type 'google::protobuf::internal::CallOnceInitializedMutex<std::mutex>' in a constant expression
In file included from lib\include/google/protobuf/descriptor.h:66:0,
from lib\include/google/protobuf/message.h:121,
from lib\include/google/protobuf/generated_message_bases.h:42,
from src/protodata/myfile.pb.h:26,
from src/myfile/myfile.h:12,
from src\myclass/myclass.h:8,
from src\mywidget.cpp:2:
lib\include/google/protobuf/stubs/mutex.h: In constructor 'constexpr google::protobuf::internal::WrappedMutex::WrappedMutex()':
lib\include/google/protobuf/stubs/mutex.h:124:29: error: temporary of non-literal type 'google::protobuf::internal::CallOnceInitializedMutex<std::mutex>' in a constant expression
constexpr WrappedMutex() {}
^
lib\include/google/protobuf/stubs/mutex.h:98:7: note: 'google::protobuf::internal::CallOnceInitializedMutex<std::mutex>' is not literal because:
class CallOnceInitializedMutex {
^~~~~~~~~~~~~~~~~~~~~~~~
lib\include/google/protobuf/stubs/mutex.h:98:7: note: 'google::protobuf::internal::CallOnceInitializedMutex<std::mutex>' has a non-trivial destructor
where the erroneous lines of code are:
// Mutex is a natural type to wrap. As both google and other organization have
// specialized mutexes. gRPC also provides an injection mechanism for custom
// mutexes.
class GOOGLE_PROTOBUF_CAPABILITY("mutex") PROTOBUF_EXPORT WrappedMutex {
public:
#if defined(__QNX__)
constexpr WrappedMutex() = default;
#else
constexpr WrappedMutex() {} // <--- Error points here
#endif
I hit the same issue when trying to use protobuf version higher than 3.15.0 with gcc 7.3 and c++17. This turned out to be a gcc bug, see more in https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82461.
After looking into the protobuf generated code, what i find is in version after 3.15, protobuf generated code container pervasive 'constexpr' which trigger the gcc bug.
Possible solution:
use higher version of gcc, the bug is fixed in 7.4 (preferred)
use '-std=c++14' instead of '-std=c++17', this works for me
use protobuf older than 3.15, 3.13 and 3.14 works for me.
In my case it was enough:
Go to your opencv folder, find the file \opencv\sources\3rdparty\protobuf\src\google\protobuf\stubs\mutex.h and delete the line after the first else at the WrappedMutex class,
class GOOGLE_PROTOBUF_CAPABILITY("mutex") PROTOBUF_EXPORT WrappedMutex {
audience:
#if defined(__QNX__)
constexpr WrappedMutex() = default;
#else
constexpr WrappedMutex() {} // **Delete this line**
#endif
tl;dr
When I try to compile this code, Visual Studio throws a compile time error for very static_assert, regardless of wheter it should, and then also one "active error" for the only one that should. This is an issue with my code, or with Visual Studio?
Visual Studio Version
Microsoft Visual Studio Community 2019
Version 16.10.2
#include <memory>
struct Node {};
struct A : Node {};
struct B : Node {};
#define cast_to_A(ptr) ([&] () { \
static_assert( \
std::is_same<std::shared_ptr<Node>, decltype(ptr)>::value, \
"Cannot cast to an A pointer." \
); \
return std::static_pointer_cast<A>(ptr); \
})()
#define cast_to_B(ptr) ([&] () { \
static_assert( \
std::is_same<std::shared_ptr<Node>, decltype(ptr)>::value, \
"Cannot cast to a B pointer." \
); \
return std::static_pointer_cast<B>(ptr); \
})()
int main() {
auto a = std::make_shared<A>();
auto b = std::make_shared<B>();
auto aAsNode = std::static_pointer_cast<Node>(a);
auto bAsNode = std::static_pointer_cast<Node>(b);
auto a1 = cast_to_A(aAsNode); // Expected: No error, Actual: "Cannot cast to an A pointer."
auto b1 = cast_to_B(bAsNode); // Expected: No error, Actual: "Cannot cast to an B pointer."
auto badCast = cast_to_A(b); // Expected & Actual: "Cannot cast to an A pointer."
return 0;
}
Context
In a personal project, I have a node struct from which a bunch of child structs inherit. Throughout the program I cast from std::shared_ptr<Node> to std::shared_ptr<Child> and vice-versa using std::static_pointer_cast. Somewhere in my program I have compile time errors where I'm acidentally trying to convert from one sibling pointer to another. However, the error is attriubted to code within std::static_pointer_cast (line 1925 of <memory>), and as it isn't a runtime error I can't move up the call stack to find where my bad call is.
As it happens, the code for my structs is procedurally generated by a python script I wrote. My attempted solution was to generate a macro for each struct (like seen in the toy example), then I just did a regex search/replace to replace all my std::static_pointer_cast calls with the appropriate macro.
The issue I have is that recreated in the toy example above. Visual Studio puts a red line under the macro "calls" that I would expect to fail (so I've actually found the bug now), but for every single use of the macro it also throws a compile time error from the static_assert, even when (to my understanding) it shouldn't fail. It doesn't put a red line under those "calls" though, so I'm unsure if this is a Visual Studio bug.
Looking around online saw that std::is_same can be quite particular about what counts as the same type or not. The variable given as the marco argument get's passed to the static_assert by reference (as it passes through the lambda's [&] capture), so I wondered if this was throwing it off. But I couldn't figure out any way to tweak the types to make it work.
Thanks in advance for any help! Any pointers or tips are much appreciated!
#1201ProgramAlarm answered in the comments. The solution was to use std::remove_reference to remove the reference added to the ptr when it is passed into the lambda. The final macro was:
#define cast_to_A(ptr) ([&] () { \
static_assert( \
std::is_same<std::shared_ptr<Node>, std::remove_reference<decltype(ptr)>::type>::value, \
"Cannot cast to an A pointer." \
); \
return std::static_pointer_cast<A>(ptr); \
})()
Now only the expected "bad cast" throws an error
I cloned the LLVM git repositories and followed https://llvm.org/docs/GettingStarted.html. After configuration with
cmake $SOURCEDIR -G "Unix Makefiles" \
-DCLANG_DEFAULT_CXX_STDLIB=libc++ \
-DC_INCLUDE_DIRS=:/usr/include \
-DLLVM_ENABLE_WERROR=OFF \
-DCMAKE_BUILD_TYPE=DEBUG \
-DCMAKE_C_COMPILER=$CC \
-DCMAKE_CXX_COMPILER=$CXX \
-DCMAKE_EXE_LINKER_FLAGS="${LDFLAGS}" \
-DCMAKE_CXX_FLAGS_RELEASE="${CXXFLAGS}" \
-DCMAKE_INSTALL_PREFIX=$INSTALLDIR \
-DCMAKE_EXPORT_COMPILE_COMMANDS=ON
I tried to build LLVM and Clang with
make -j 24
but it failes (I added new lines for improved readability):
/home/myUserName/LLVM/sources/tools/clang/utils/TableGen/ClangAttrEmitter.cpp:
In constructor β{anonymous}::EnumArgument::EnumArgument(const llvm::Record&, llvm::StringRef)β:
/home/myUserName/LLVM/sources/tools/clang/utils/TableGen/ClangAttrEmitter.cpp:740:42:
error: no matching function for call to
βstd::vector<std::__cxx11::basic_string<char> >::vector(std::vector<llvm::StringRef>)β
uniques(uniqueEnumsInOrder(enums))
^
Unfortunately I don't understand why there is a problem, since this function should be declared in
tools/clang/utils/TableGen/ClangAttrEmitter.cpp:722.
This is an excerpt of the corresponding code:
// Unique the enums, but maintain the original declaration ordering.
std::vector<std::string>
uniqueEnumsInOrder(const std::vector<std::string> &enums) {
std::vector<std::string> uniques;
SmallDenseSet<StringRef, 8> unique_set;
for (const auto &i : enums) {
if (unique_set.insert(i).second)
uniques.push_back(i);
}
return uniques;
}
class EnumArgument : public Argument {
std::string type;
std::vector<std::string> values, enums, uniques;
public:
EnumArgument(const Record &Arg, StringRef Attr)
: Argument(Arg, Attr), type(Arg.getValueAsString("Type")),
values(Arg.getValueAsListOfStrings("Values")),
enums(Arg.getValueAsListOfStrings("Enums")),
uniques(uniqueEnumsInOrder(enums))
{
// FIXME: Emit a proper error
assert(!uniques.empty());
}
I use gcc 7.2.0 and Ubuntu 16.04.3 LTS.
Update:
In the meantime I had the chance to build LLVM+Clang with gcc 5.4.0 and the build finished successfully. Does this mean that there is a compiler bug oder is it an issue respectively the gcc standard?
I copied a Big Int Library into my code and I'm having random errors in one of the classes. (The code is older)
One of my errors is in a define statement, not really sure how these work.
Everything under "tmpthis;" is giving an error.
#define DTRT_ALIASED(cond, op) \
if (cond) {\
BigUnsigned tmpThis;
tmpThis.op; //Error: no storage class or type specifier
*this = tmpThis; //Error: *this expected an identifier Error: No suitable conversion from "BigUnsigned" to "int" exists.
return; // Error: expected a declaration
} \
On top of that there are a few random if and for statements with the error "expected a declaration" and some variables with the error " no storage class or type specifier"
NOTE: these random errors also had instances where they were not errors also, it was inconsistent.
A bare-bones fix to the macro is:
#define DTRT_ALIASED(cond, op) \
if (cond) { \
BigUnsigned tmpThis; \
tmpThis.op; \
*this = tmpThis; \
return; \
}
This stands a chance of compiling when used in a function that doesn't return a value, if the reference to op in tmpThis.op makes sense to the compiler. It is somewhat peculiar (and limited) code, but there might be a use for it.
I am seeing a weird crash trying to use a wrapper template class around aligned struct/class. The following program is crashing when compiled with clang, while working properly with both gcc and visual studio.
struct __attribute__( ( aligned( 16 ) ) ) AlignedStruct
{
AlignedStruct( ) { }
float x,y,z,w;
};
template <typename P1> class Wrapper
{
public:
P1 Inner;
};
int main( )
{
Wrapper<AlignedStruct> * t1 = new Wrapper<AlignedStruct>( );
return 1;
}
The crash seems to be while calling AlignedStruct constructor (if I remove it, clang compiled code runs as well).
Can anyone explain what is going on here?
Thanks!
Edit:
The crash occurs with clang 3.4.2 under cygwin32 and cygwin64
and clang 3.4.1 under Ubuntu 14.04 (x32) and Ubuntu 14.10 (x32)
It does not, however, occur when testing with clang 3.4.1 under FreeBSD 10.1 (x32) and OS X Yosemite.
I've tried playing around with compilation flags but I can't seem to be able to make any difference with those, so I am just running clang++ file.cpp