Intel® oneAPI Threading Building Blocks
Ask questions and share information about adding parallelism to your applications when using this threading library.

Question about atomic.

isnork
Beginner
535 Views
Hi,

I get this error when doing using a static atomic counter.

In the the class .h file:

[cpp]static tbb::atomic counter;[/cpp]

In the the class .cpp file:
[cpp]tbb::atomic MyClass::counter = 0;[/cpp]
So, when compiling g++ yields this : error: conversion from int to non-scalar type tbb::atomic requested.

I don't get it. Aren't static attributes initialized this way? So why the int to tbb::atomic conversion?

Thanks!
0 Kudos
1 Solution
RafSchietekat
Valued Contributor III
535 Views
Leave out the "= 0" and thereby rely on zero-initialisation. Blame C++, not TBB.

(Added 2011-12-19) Also see Tutorial "Why atomic Has No Constructors".

View solution in original post

0 Kudos
7 Replies
SergeyKostrov
Valued Contributor II
535 Views
Note: Thanks for the Test-Case!!!

>>...Aren't static attributes initialized this way?

When it comes to a regular static member,'int' type for example,of some class your declaration is
absolutely correct. But, 'tbb::atomic< ... >' is a template class.

>>...So why the int to tbb::atomic conversion?

Because '0' has a type 'int' and 'counter' has a type 'tbb:atomic' and that is whythe C/C++ compiler
failedto do a proper conversion. It looks like there is no a C++ operator '=' to do this.

...

#include "tbb/atomic.h"
...
class CTestAtomic
{
public:
CTestAtomic(){};
virtual ~CTestAtomic(){};

static tbb::atomic< int > iCounter;
static tbb::atomic< long > &lCounter;
static tbb::atomic< long long > llCounter;
};
...
tbb::atomic< int > aInt;
tbb::atomic< int > CTestAtomic::iCounter = aInt;

tbb::atomic< long > aLong;
tbb::atomic< long > & CTestAtomic::lCounter = aLong;

tbb::atomic< long long > CTestAtomic::llCounter;
...

Please take a look at the enclosed picture.

0 Kudos
RafSchietekat
Valued Contributor III
536 Views
Leave out the "= 0" and thereby rely on zero-initialisation. Blame C++, not TBB.

(Added 2011-12-19) Also see Tutorial "Why atomic Has No Constructors".
0 Kudos
jimdempseyatthecove
Honored Contributor III
535 Views
I haven't tried this...

tbb:atomic foo = reinterpret_cast>(0);

Jim
0 Kudos
RafSchietekat
Valued Contributor III
535 Views
Hmm, you obviously didn't try that...

I can confirm success with "int foo = 1; tbb::atomic bar = (tbb::atomic&)foo;", but I have little hope for literals. It may be that in C++11 something essential has changed to allow constructors to be added and still have zero-initialisaton when desired (early during program startup), but I haven't explored that yet, and it would probably require a version-specific adaptation to the source code for tbb::atomic.

But often you can just rely on zero-initialisation alone (either for globals or static members, or by mentioning "m_foo()" in an object constructor's initialisation list), and using simple assignment doesn't seem like such an awful concession to make...
0 Kudos
isnork
Beginner
535 Views
Ok!!!

Thank you very much, guys!
0 Kudos
RafSchietekat
Valued Contributor III
535 Views
"I have little hope for literals"
Hmm... how about "template tbb::atomic to_atomic(T t) { tbb::atomic a; a.store<:RELAXED>(t); return a; }"? Now that I haven't tested, but if it works then it should be possible to do "tbb::atomic bar = tbb::to_atomic(1);" in an upcoming version (hint).

(Added 2011-12-18) Tested successfully, but I would now propose tbb::make_atomic instead (as in std::make_pair, etc.).
0 Kudos
SergeyKostrov
Valued Contributor II
535 Views
Here is a list of All different variants I tried:

// V1
tbb::atomic< int > CTestAtomic::iCounter = 0; // Error C2440: 'initializing' : Cannot convert from 'int' to 'tbb::atomic'

// V2
tbb::atomic< int > CTestAtomic::iCounter = static_cast< tbb::atomic< int > >( 0 ); // Error C2440: 'static_cast' : Cannot convert from 'int' to 'tbb::atomic'

// V3
tbb::atomic< int > CTestAtomic::iCounter = dynamic_cast< tbb::atomic< int > >( 0 ); // Error C2680: 'tbb::atomic' : Invalid target type for dynamic_cast

// V4
tbb::atomic< int > CTestAtomic::iCounter = reinterpret_cast< tbb::atomic< int > >( 0 );// Error C2440: 'reinterpret_cast' : cannot convert from 'int' to 'tbb::atomic'

// V5
int aInt = 777;
tbb::atomic< int > CTestAtomic:: iCounter = ( tbb::atomic< int > & )aInt;// Success for a Static member of a class

// V6
tbb::atomic< int > iCounter = ( tbb::atomic< int > & )aInt; // Success for a Non Static variable

// V7
tbb::atomic< int > aInt;
tbb::atomic< int > CTestAtomic::iCounter = aInt; // Success

// V8
tbb::atomic< long > aLong;
tbb::atomic< long > & CTestAtomic::lCounter = aLong;// Success

// V9
tbb::atomic< long long > CTestAtomic::llCounter; // Success
0 Kudos
Reply