2

I have a instruction in my code calling function __atomic_add_fetch. When I compile this code, I am getting compilation error as below

error: undefined reference to '__atomic_fetch_add_8'

I really could not understand why it is throwing undefined reference to __atomic_fetch_add_8 when I am calling __atomic_add_fetch. Could somebody please help me understand what exactly happening while compiling this code?

Note: I am specifically looking to understand "what is internally happening that translates __atomic_add_fetch into __atomic_fetch_add_8". Not the solution to fix compilation issue.

Pendyala
  • 585
  • 1
  • 6
  • 17

1 Answers1

8

You should be using the standardized atomic_fetch_add.

In any case, it looks like your __atomic_fetch_add with the given argument type (presumably an 8-byte integer) cannot be resolved to an assembly instruction(s) on your platform so it is getting resolved to a function call for which you'll need to link libatomic (-latomic).

Edit with details:

On gcc, __atomic_fetch_add appears to be the compiler built in used to implement stdatomic.h's atomic_fetch_and_explicit (which is just a simple macro name for it). As I've noted, you should really be using the standard name atomic_fetch_add_explicit, not the nonportable implementation detail that __atomic_fetch_add is.

Regardless, the issue seems to be that gcc and clang don't implement atomic_fetch_and_explicit with instructions on ARM (unlike on ARM64 or x86-64) but instead they generate a call to a (global-lock-using) function from the libatomic library. The name of the function seems to be derived from the number of bytes in the integer you're trying to fetch_add to (__atomic_fetch_add_8 if you're fetch_adding to _Atomic uin64_t __atomic_fetch_add_4 if you're fetch_adding to _Atomic uin32_t, etc.).

https://gcc.godbolt.org/z/S67g7b

Petr Skocik
  • 58,047
  • 6
  • 95
  • 142
  • 1
    thanks for the quick reply. The same code is successfully compiled when I am using GNUSTL as standard library. But when I am using libc++, it is failing. Please let me know if you have any idea about this. – Pendyala May 16 '19 at 13:02
  • 4
    @Pendyala -- `__atomic_fetch_add` is not part of standard C++. The name starts with two underscores, so the name is reserved for use by the implementation. Seems like you're looking at an implementation detail. Use `atomic_fetch_add`. – Pete Becker May 16 '19 at 13:16
  • 1
    @PSKocik, could you please provide some insights about what exactly is happening when __atomic_add_fetch is compiled (particularly why it is showing undefined referenc to __atomic_fetch_add_8). Googled a lot, but could not find any information. – Pendyala May 16 '19 at 18:10
  • 1
    @Pendyala I suggest you *post the code* that is failing to compile. – pmdj May 16 '19 at 19:51
  • 1
    @Pendyala You are using a (non-portable) compiler intrinsic. When you do that, what happens is: whatever the compiler has been implemented to do - and that could be *anything*. If you really want to know - go look at the gcc source. – Martin Bonner supports Monica May 16 '19 at 19:53