Compiling with Intel Threading Building Blocks: error operands to ?: - c++

Currently, I try to compile OpenVDB, which depends on Threading Building Blocks. I get the following error:
In file included from /usr/include/tbb/enumerable_thread_specific.h:32:0,
from ../openvdb/tools/Morphology.h:59,
from ../openvdb/tools/MultiResGrid.h:64,
from cmd/openvdb_lod/main.cc:32:
/usr/include/tbb/concurrent_vector.h: In member function ‘tbb::concurrent_vector<T, A>::iterator tbb::concurrent_vector<T, A>::grow_by(tbb::concurrent_vector<T, A>::size_type)’:
/usr/include/tbb/concurrent_vector.h:667:38: error: operands to ?: have different types ‘tbb::internal::concurrent_vector_base_v3::size_type {aka long unsigned int}’ and ‘tbb::atomic<long unsigned int>’
return iterator(*this, delta ? internal_grow_by( delta, sizeof(T), &initialize_array, NULL ) : my_early_size);
~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/usr/include/tbb/concurrent_vector.h:667:38: note: and each type can be converted to the other
/usr/include/tbb/concurrent_vector.h: In member function ‘tbb::concurrent_vector<T, A>::iterator tbb::concurrent_vector<T, A>::grow_by(tbb::concurrent_vector<T, A>::size_type, tbb::concurrent_vector<T, A>::const_reference)’:
/usr/include/tbb/concurrent_vector.h:680:38: error: operands to ?: have different types ‘tbb::internal::concurrent_vector_base_v3::size_type {aka long unsigned int}’ and ‘tbb::atomic<long unsigned int>’
return iterator(*this, delta ? internal_grow_by( delta, sizeof(T), &initialize_array_by, static_cast<const void*>(&t) ) : my_early_size);
~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/usr/include/tbb/concurrent_vector.h:680:38: note: and each type can be converted to the other
make: *** [vdb_lod] Error 1
In short, as second and third argument, the ?: operator gets one base type and the same base type wrapped in tbb::atomic, with the compiler not knowing which type to use as return value.
Needless to say, I have no intentions of changing that source code. Since they are established products, it's safe to say that I do something wrong at compiling.
The TBB library file seems to be build with rather old versions of GCC, that is 4.7. I originally thought that the problem might be that I used GCC 7.2.0, therefore I tried out different versions, like GCC 4.8.5, but the error persists.
I haven't tried out 4.7 in particular since I work in a company where I don't have admin rights, and I try to avoid a local installation of GCC. Especially since I don't know if GCC is even the issue here.
Does anyone know a fix to that?
Edit: https://software.intel.com/en-us/forums/intel-threading-building-blocks/topic/417161 seems to be about the same problem, and an employee from Intel noted it for change in there. However, that post was from 2013 and since people used TBB in-between, there must be something I do different in general.

It looks like that an outdated TBB version is used.
See the similar question on the TBB forum.

Related

Why does this library refrain from using static_cast?

I try to follow the mantra of "no warnings." I try to write my code so that the compiler gives no warnings. I'm starting to use non-standard libraries for the first time.
I recently installed mlpack (with armadillo) using
vcpkg install mlpack:x64-windows
I built the library and it works. However, my compiler gives loads of warnings. These warnings seem like they could have been fixed by the developer, but I'm not sure.
Many of the warnings are about conversions. For example, the first such compiler warning is
'argument': conversion from 'size_t' to 'const arma::arma_rng::seed_type', possible loss of data
This occurs in the line
arma::arma_rng::set_seed(seed);
where seed is always of type const size_t. I made the following change:
arma::arma_rng::set_seed(static_cast<arma::arma_rng::seed_type>(seed));
This removed the warning. Another fix is to overload arma::arma_rng::set_seed to take a double and perform the conversion within the function.
Given that the armadillo library is so popular, I assume someone at some point would have recommended these changes. Is there a reason not to add static_cast here (i.e., is this an optimization)?
I dont have the library available, so I'll use a different example. Consider the following code is in the library. Its a completely made up example, but I hope it resembles the situation more or less:
#include <iostream>
void foo(unsigned char x) {
std::cout << (int)x << "\n";
}
void bar_warn(int a){
foo(a);
}
void bar_no_warn(int a){
foo(static_cast<unsigned char>(a));
}
gcc warns for bar_warn but not for bar_no_warn:
<source>:4:9: error: conversion from 'int' to 'unsigned char' may change value [-Werror=conversion]
4 | foo(a);
| ^
The std::cout << (int)x is just to see the effect of following user code:
int main() {
bar_warn(123456);
bar_no_warn(123456);
}
Output is
64
64
That is: The user code is completely fine. It has no errors nor does it trigger warnings. The issue is in the library code. The cast does change the value. And that is the case with or without the static cast. The static cast does not "fix" the cast in any way, it merely silences the warning.
If you can browse all usages of the cast and make sure that the reason for the warning never takes place then you can use a static_cast to silence the warning. In library code that is not always possible. The library cannot foresee all usages. User code might pass a value that is too big and a user might get unexpected results. In such case it is better for the library to warn rather than to silence the warning.
If you are bothered by the warning you can still silence it. For example gcc has -isystem to not output warnings in system headers. I suppose other compilers have similar option.

use boost::polygon with boost::multiprecision

I'm trying to use boost::polygon with boost::multiprecision to calculate polygon differences but no matter how i try to combine the two, i'm always getting compiler errors like
assigning to 'long double' from incompatible type 'boost::multiprecision::number<boost::multiprecision::backends::cpp_int_backend<0, 0, boost::multiprecision::signed_magnitude, boost::multiprecision::unchecked, std::allocator<unsigned long long>>, boost::multiprecision::et_off>'
in
https://github.com/boostorg/polygon/blob/develop/include/boost/polygon/detail/polygon_arbitrary_formation.hpp#L401
and similar places when trying to read back the results:
using DifferenceResults = std::vector<gtl::polygon_with_holes_data<ValueType>>;
DifferenceResults differenceResult;
result.value().get<DifferenceResults>(differenceResult);
Here's what i tried.
Am i doing this right?
I tried different things for coordinate_traits but at the end it looks like the types and expressions used in the lazy functions like evalAtXforYlazy refuse to support this.
It compiles fine without multiprecision.
I also tried to modify polygon_arbitryry_formation.hpp and added explicit casts wherever needed which was promising at first but at the end lead me to overload resultion problems here which originate here.
I further tried to replace boost.multiprecision with MPIR but they don't even have explicit cast operators but just member functions for conversions which would be even less compatible with evalAtXforYlazy and others.
What am i doing wrong?

How to fully bypass `error: no match for ‘operator==’`?

I am using a program called SlideSort, which does not compile anymore on a recent Debian system using GCC 6.3.0. Instead, it throws the following error:
mstree.cpp:228:11: error: no match for ‘operator==’ (operand types are ‘std::ofstream {aka std::basic_ofstream<char>}’ and ‘long int’)
if(dFile==NULL){
^
Not being a C programmer, I tried to bypass the problem by gently telling the compiler that the code is old; in my understanding this is roughly what GCC's option -std=c++98 does. (See in GitHub's issue tracker for the patch to the Makefile).
Then the code compiles. but it segfaults in some corner cases (Test data and command available in GitHub's issue tracker). The same test command works fine when the program is compiled with GCC 4.9.4.
Thus, passing -std=c++98 to GCC was either not enough or a wrong idea altogether. Is there an alternative to either compile on an old system or updated the code to the latest standards (which I can not do by myself) ?
I do not know why this code ever worked. In no version of the C++ standard is a scalar stream object comparable to an integer or to nullptr_t. That being said, your question is not how to fix the code you've found but how to bypass the error. I do not recommend doing what I'm about to say here in production code. It's a hack, and it's only designed to get an unusual library like this working.
The == operator can be defined outside of any class, as a standalone function. The library you're using compares std::ofstream to long int. Let's make that comparison valid.
bool operator==(const std::ofstream&, long int) {
return false;
}
Now your code will compile. But it will probably run incorrectly. You could try making the comparison smarter by having it check whether the std::ofstream is truthy.
bool operator==(const std::ofstream& out, long int n) {
return (bool)out == (bool)n;
}
Now it's a bit smarter. But there's no silver bullet here. The code you were given is not working and not standard C++, so there's no fullproof way to get it working without changing the actual library code. So my suggestion is to fork the repository and fix the broken line of code yourself.
In C++ 98 the streams used to have an operator void*() to check the stream state. It returned a null pointer when the stream was in an error state. Turned out that this implicit conversion caused some unexpected results when accidentally invoked in odd places.
So in C++11, which gained explicit operators, it was turned into an explicit operator bool() instead. This returns true for a good state and false when the stream is in a failed state.
Being explicit it can also only be used in places where a bool is expected. This removes most of the unexpected conversions from the old operator.
So if(dFile==NULL), testing for a non-good state of the stream, is now written if (!dFile).
And actually, the tests if (dfile) (good state) and if (!dFile) (non-good state) have always worked. The comparison against NULL has never been required, it just happened to work when the operator returned a void*.
My guess is this (if(dFile==NULL){) if condition is trying to check whether a file was open successfully for writing, if so you use function is_open which is available in c++. So simply replace the condition by if (dFile.is_open()). This should do the trick.
Without knowing the rest of the code, you can just try to rephrase that line such as:
if(!dFile)
See what happens next.

reinterpret_cast from type 'const char*' to type '__FlashStringHelper*' casts away qualifiers

I want to use Adafruit_CC3000 arduino library in AVR Studio. I have followed this Instruction to use Adafruit arduino lib with AVR studio so i can use other AVR function too. But I am getting the same error 50 times while i compile the code.
Error 5 reinterpret_cast from type 'const char*' to type
'__FlashStringHelper*' casts away
qualifiers E:\arduino-1.0.1\libraries\Adafruit_CC3000\Adafruit_CC3000.cpp 183 3 ATmega32_WSClient_CC3K
I have searched on web for such kind of errors. but i failed to understand the issue. I am requesting to make me understand which thing in this code is generatig this error?
reinterpret_cast can convert between unrelated pointer types, but can't remove const or volatile qualifiers. You need const_cast for that.
Options are (roughly in order of increasing nastiness):
don't use the wrong pointer type in the first place;
cast to const __FlashStringHelper*, if you don't need to modify the object;
cast from char* if you do need to modify it;
use reinterpret_cast<__FlashStringHelper*>(const_cast<char*>(whatever)) or the brute-force (__FlashStringHelper*)whatever if you insist on abandoning the type system entirely.

C++11 for xCode errors

I want to use std collections, for example std::vector in my xCode 4.5 project. Following the explanation here no type named 'shared_ptr' in namespace 'std' I changed my compiler options accordingly, but now when I come to build the project I get a bunch of errors such as Type float cannot be narrowed to GLubyte (aka unsigned char) in initializer list.
These errors are in a ccType.h, which is part of the Cocos2d library I'm using for my game.
I'm thinking the right thing to do is not to start debugging Cocos2d, but to change some of the compiler options.
How should I proceed?
Here is the code that causes the errors:
static inline ccColor4B ccc4BFromccc4F(ccColor4F c) {
return (ccColor4B){c.r*255.f, c.g*255.f, c.b*255.f, c.a*255.f};
}
The error message is exactly as I brought it above.
You should cast the type accordingly because C++11 disallow implicit conversion in initialisers lists, specifically in this case from float to unsigned char.
I guess this should be enough to solve the issue:
return (ccColor4B){static_cast<GLubyte>(c.r*255.f), static_cast<GLubyte>(c.g*255.f), static_cast<GLubyte>(c.b*255.f), static_cast<GLubyte>(c.a*255.f)};