1

I'm rewriting this c# code to c++:

public class LightOrder
{
    private static int internalIdCounter;

    public int InternalId { get; private set; }

    // i control myself to call this method exactly once for each order
    public void AssignInternalId(int ordersExecutorId)
    {
        // if InternalId is already assigned, i.e. != 0, i can print error or something
        InternalId = Interlocked.Increment(ref internalIdCounter);
        // more
    }

    // more
}

This works fine - each order has sequential id even if AssignInternalId is called from different threads parallel.

What is closest c++ equavalent to this code? Should I declare InternalId as std::atomic<int> and then just use ++? Or I should declare InternalId as int and use something like std::atomic_fetch_add?

Oleg Vazhnev
  • 21,122
  • 47
  • 154
  • 286
  • Using the MS C++ equivalent of the C# function is probably the best bet: http://msdn.microsoft.com/en-us/library/windows/desktop/ms683614%28v=vs.85%29.aspx – sashang Apr 22 '14 at 09:40
  • 1
    @sashang: I don't see why, when C++ already provides standard functionality for this in the form of `std::atomic`. [std::atomic::operator++](http://en.cppreference.com/w/cpp/atomic/atomic/operator_arith) does exactly what is needed here. – Mankarse Apr 22 '14 at 09:46
  • @Mankarse: But how is std::atomic::operator++ imlpemented on Windows? If it's defined the same as InterlockedIncrement then that would be fine. – sashang Apr 22 '14 at 09:54
  • @Mankarse: Also InterlockedIncrement is closer in terms of translation between C# and C++ thane std::atomic::operator++ which is only in c++11. – sashang Apr 22 '14 at 09:57
  • @sashang i would prefer to use c++11 function instead of Windows API for better portability. – Oleg Vazhnev Apr 22 '14 at 09:58
  • 1
    @javapowered: Yeah if portability is a concern this is true. If you want to compile with a VC++ 2005 then it's not. If you are concerned about the closest representation then it's not, and the question seemed to be asking about the closest representation. – sashang Apr 22 '14 at 10:02

2 Answers2

5

Should I declare InternalId as std::atomic<int> and then just use ++?

Yes.

Or I should declare InternalId as int and use something like std::atomic_fetch_add?

No. Functions like atomic_fetch_add only work on atomic types (specialisations of atomic, or types like atomic_int), so you'd still need an atomic type.

Mike Seymour
  • 235,407
  • 25
  • 414
  • 617
3

Since it is incrementing an integer, using just std::atomic will do the thing:

   std::atomic<int> internalId;

   public:
      void assignInternalId()
      {
         ++internalId;
      }
      int internalId() 
      {
         return internalId.load();
      }
Kao
  • 6,619
  • 7
  • 39
  • 64
  • No. As in the question, you'd have a static atomic counter, and a non-static non-atomic (and probably constant) variable initialised by incrementing and reading the counter. – Mike Seymour Apr 22 '14 at 09:58
  • Yep, that's true. You can see Yep, that's true. You can see [this](http://stackoverflow.com/questions/18850752/) for more details – Kao Apr 22 '14 at 10:04