Question about atomic.

Question about atomic.

Hi,

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

In the the class .h file:

static tbb::atomic counter;

In the the class .cpp file:

tbb::atomic MyClass::counter = 0;

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!

8 posts / 0 new
Last post
For more complete information about compiler optimizations, see our Optimization Notice.

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.

Raf Schietekat's picture
Best Reply

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".

jimdempseyatthecove's picture

I haven't tried this...

tbb:atomic foo = reinterpret_cast>(0);

Jim

www.quickthreadprogramming.com
Raf Schietekat's picture

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...

Ok!!!

Thank you very much, guys!

Raf Schietekat's picture

"I have little hope for literals"
Hmm... how about "template tbb::atomic to_atomic(T t) { tbb::atomic a; a.store(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.).

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

Login to leave a comment.