dsyleixa123
Posts: 1493
Joined: Mon Jun 11, 2018 11:22 am

Re: atomic or volatile, that is the question ( Whether 'tis nobler in the mind to mutex them)

Fri Jun 18, 2021 9:21 am

well, I am using multithreading successfully since 10 years and more, all is fine (using volatile + mutexes + thread prios) - I only need to understand atomic which had been suggested, and answers should be suitable for non-professionals, finally the Pi is also for beginners. The answers given by tttapa so far thankfully actually are suitable for beginners (e.g., for me), just missing some details.

updated by my tests:
the test program with some extra printfs works fine, even the initialization is apparently correct.

Code: Select all

#include <stdatomic.h>
#include <stdbool.h>
#include <stdio.h>

static _Atomic int myval = 1;
static _Atomic bool flag = true;

int main() {
    printf("myval=%d  flag=%d \n", myval, flag);
    myval = 42;
    flag = false;
    myval |= 7;
    printf("myval=%d  flag=%d \n", myval, flag);
}

Code: Select all

gcc  -Wall -I/opt/vc/include -o  "atomic_test001" "atomic_test001.c" -pthread -I/opt/vc/include -lshapes -lwiringPi -lpigpio -lrt $(pkg-config eigen3 --cflags) -lreadline  -lArduiPi_OLED (im Verzeichnis: /home/pi/raspiProgs/threadprogs)
Kompilierung erfolgreich beendet.
output:

Code: Select all

myval=1  flag=1 
myval=47  flag=0


------------------
(program exited with code: 0)
Press return to continue
But if I compile the same code optionally by g++ (as it will have to fit optionally/arbitrarily also for C++ programs in future, e.g. inside of qt5 creator) then I get lot of errors:

Code: Select all

g++ -Wall -I/opt/vc/include -o  "atomic_test001" "atomic_test001.c" -pthread -I/opt/vc/include -lshapes -lwiringPi -lpigpio -lrt $(pkg-config eigen3 --cflags) -lreadline  -lArduiPi_OLED (im Verzeichnis: /home/pi/raspiProgs/threadprogs)
In file included from atomic_test001.c:1:0:
/usr/lib/gcc/arm-linux-gnueabihf/6/include/stdatomic.h:40:9: error: ‘_Atomic’ does not name a type
 typedef _Atomic _Bool atomic_bool;
         ^~~~~~~
/usr/lib/gcc/arm-linux-gnueabihf/6/include/stdatomic.h:41:9: error: ‘_Atomic’ does not name a type
 typedef _Atomic char atomic_char;
         ^~~~~~~
/usr/lib/gcc/arm-linux-gnueabihf/6/include/stdatomic.h:42:9: error: ‘_Atomic’ does not name a type
 typedef _Atomic signed char atomic_schar;
         ^~~~~~~
/usr/lib/gcc/arm-linux-gnueabihf/6/include/stdatomic.h:43:9: error: ‘_Atomic’ does not name a type
 typedef _Atomic unsigned char atomic_uchar;
         ^~~~~~~
/usr/lib/gcc/arm-linux-gnueabihf/6/include/stdatomic.h:44:9: error: ‘_Atomic’ does not name a type
 typedef _Atomic short atomic_short;
         ^~~~~~~
/usr/lib/gcc/arm-linux-gnueabihf/6/include/stdatomic.h:45:9: error: ‘_Atomic’ does not name a type
 typedef _Atomic unsigned short atomic_ushort;
         ^~~~~~~
/usr/lib/gcc/arm-linux-gnueabihf/6/include/stdatomic.h:46:9: error: ‘_Atomic’ does not name a type
 typedef _Atomic int atomic_int;
         ^~~~~~~
/usr/lib/gcc/arm-linux-gnueabihf/6/include/stdatomic.h:47:9: error: ‘_Atomic’ does not name a type
 typedef _Atomic unsigned int atomic_uint;
         ^~~~~~~
/usr/lib/gcc/arm-linux-gnueabihf/6/include/stdatomic.h:48:9: error: ‘_Atomic’ does not name a type
 typedef _Atomic long atomic_long;
         ^~~~~~~
/usr/lib/gcc/arm-linux-gnueabihf/6/include/stdatomic.h:49:9: error: ‘_Atomic’ does not name a type
 typedef _Atomic unsigned long atomic_ulong;
         ^~~~~~~
/usr/lib/gcc/arm-linux-gnueabihf/6/include/stdatomic.h:50:9: error: ‘_Atomic’ does not name a type
 typedef _Atomic long long atomic_llong;
         ^~~~~~~
/usr/lib/gcc/arm-linux-gnueabihf/6/include/stdatomic.h:51:9: error: ‘_Atomic’ does not name a type
 typedef _Atomic unsigned long long atomic_ullong;
         ^~~~~~~
/usr/lib/gcc/arm-linux-gnueabihf/6/include/stdatomic.h:52:9: error: ‘_Atomic’ does not name a type
 typedef _Atomic __CHAR16_TYPE__ atomic_char16_t;
         ^~~~~~~
/usr/lib/gcc/arm-linux-gnueabihf/6/include/stdatomic.h:53:9: error: ‘_Atomic’ does not name a type
 typedef _Atomic __CHAR32_TYPE__ atomic_char32_t;
         ^~~~~~~
/usr/lib/gcc/arm-linux-gnueabihf/6/include/stdatomic.h:54:9: error: ‘_Atomic’ does not name a type
 typedef _Atomic __WCHAR_TYPE__ atomic_wchar_t;
         ^~~~~~~
/usr/lib/gcc/arm-linux-gnueabihf/6/include/stdatomic.h:55:9: error: ‘_Atomic’ does not name a type
 typedef _Atomic __INT_LEAST8_TYPE__ atomic_int_least8_t;
         ^~~~~~~
/usr/lib/gcc/arm-linux-gnueabihf/6/include/stdatomic.h:56:9: error: ‘_Atomic’ does not name a type
 typedef _Atomic __UINT_LEAST8_TYPE__ atomic_uint_least8_t;
         ^~~~~~~
/usr/lib/gcc/arm-linux-gnueabihf/6/include/stdatomic.h:57:9: error: ‘_Atomic’ does not name a type
 typedef _Atomic __INT_LEAST16_TYPE__ atomic_int_least16_t;
         ^~~~~~~
/usr/lib/gcc/arm-linux-gnueabihf/6/include/stdatomic.h:58:9: error: ‘_Atomic’ does not name a type
 typedef _Atomic __UINT_LEAST16_TYPE__ atomic_uint_least16_t;
         ^~~~~~~
/usr/lib/gcc/arm-linux-gnueabihf/6/include/stdatomic.h:59:9: error: ‘_Atomic’ does not name a type
 typedef _Atomic __INT_LEAST32_TYPE__ atomic_int_least32_t;
         ^~~~~~~
/usr/lib/gcc/arm-linux-gnueabihf/6/include/stdatomic.h:60:9: error: ‘_Atomic’ does not name a type
 typedef _Atomic __UINT_LEAST32_TYPE__ atomic_uint_least32_t;
         ^~~~~~~
/usr/lib/gcc/arm-linux-gnueabihf/6/include/stdatomic.h:61:9: error: ‘_Atomic’ does not name a type
 typedef _Atomic __INT_LEAST64_TYPE__ atomic_int_least64_t;
         ^~~~~~~
/usr/lib/gcc/arm-linux-gnueabihf/6/include/stdatomic.h:62:9: error: ‘_Atomic’ does not name a type
 typedef _Atomic __UINT_LEAST64_TYPE__ atomic_uint_least64_t;
         ^~~~~~~
/usr/lib/gcc/arm-linux-gnueabihf/6/include/stdatomic.h:63:9: error: ‘_Atomic’ does not name a type
 typedef _Atomic __INT_FAST8_TYPE__ atomic_int_fast8_t;
         ^~~~~~~
/usr/lib/gcc/arm-linux-gnueabihf/6/include/stdatomic.h:64:9: error: ‘_Atomic’ does not name a type
 typedef _Atomic __UINT_FAST8_TYPE__ atomic_uint_fast8_t;
         ^~~~~~~
/usr/lib/gcc/arm-linux-gnueabihf/6/include/stdatomic.h:65:9: error: ‘_Atomic’ does not name a type
 typedef _Atomic __INT_FAST16_TYPE__ atomic_int_fast16_t;
         ^~~~~~~
/usr/lib/gcc/arm-linux-gnueabihf/6/include/stdatomic.h:66:9: error: ‘_Atomic’ does not name a type
 typedef _Atomic __UINT_FAST16_TYPE__ atomic_uint_fast16_t;
         ^~~~~~~
/usr/lib/gcc/arm-linux-gnueabihf/6/include/stdatomic.h:67:9: error: ‘_Atomic’ does not name a type
 typedef _Atomic __INT_FAST32_TYPE__ atomic_int_fast32_t;
         ^~~~~~~
/usr/lib/gcc/arm-linux-gnueabihf/6/include/stdatomic.h:68:9: error: ‘_Atomic’ does not name a type
 typedef _Atomic __UINT_FAST32_TYPE__ atomic_uint_fast32_t;
         ^~~~~~~
/usr/lib/gcc/arm-linux-gnueabihf/6/include/stdatomic.h:69:9: error: ‘_Atomic’ does not name a type
 typedef _Atomic __INT_FAST64_TYPE__ atomic_int_fast64_t;
         ^~~~~~~
/usr/lib/gcc/arm-linux-gnueabihf/6/include/stdatomic.h:70:9: error: ‘_Atomic’ does not name a type
 typedef _Atomic __UINT_FAST64_TYPE__ atomic_uint_fast64_t;
         ^~~~~~~
/usr/lib/gcc/arm-linux-gnueabihf/6/include/stdatomic.h:71:9: error: ‘_Atomic’ does not name a type
 typedef _Atomic __INTPTR_TYPE__ atomic_intptr_t;
         ^~~~~~~
/usr/lib/gcc/arm-linux-gnueabihf/6/include/stdatomic.h:72:9: error: ‘_Atomic’ does not name a type
 typedef _Atomic __UINTPTR_TYPE__ atomic_uintptr_t;
         ^~~~~~~
/usr/lib/gcc/arm-linux-gnueabihf/6/include/stdatomic.h:73:9: error: ‘_Atomic’ does not name a type
 typedef _Atomic __SIZE_TYPE__ atomic_size_t;
         ^~~~~~~
/usr/lib/gcc/arm-linux-gnueabihf/6/include/stdatomic.h:74:9: error: ‘_Atomic’ does not name a type
 typedef _Atomic __PTRDIFF_TYPE__ atomic_ptrdiff_t;
         ^~~~~~~
/usr/lib/gcc/arm-linux-gnueabihf/6/include/stdatomic.h:75:9: error: ‘_Atomic’ does not name a type
 typedef _Atomic __INTMAX_TYPE__ atomic_intmax_t;
         ^~~~~~~
/usr/lib/gcc/arm-linux-gnueabihf/6/include/stdatomic.h:76:9: error: ‘_Atomic’ does not name a type
 typedef _Atomic __UINTMAX_TYPE__ atomic_uintmax_t;
         ^~~~~~~
/usr/lib/gcc/arm-linux-gnueabihf/6/include/stdatomic.h:218:9: error: ‘_Atomic’ does not name a type
 typedef _Atomic struct
         ^~~~~~~
/usr/lib/gcc/arm-linux-gnueabihf/6/include/stdatomic.h:225:3: error: ‘atomic_flag’ does not name a type
 } atomic_flag;
   ^~~~~~~~~~~
/usr/lib/gcc/arm-linux-gnueabihf/6/include/stdatomic.h:230:8: error: ‘_Bool’ does not name a type
 extern _Bool atomic_flag_test_and_set (volatile atomic_flag *);
        ^~~~~
/usr/lib/gcc/arm-linux-gnueabihf/6/include/stdatomic.h:233:8: error: ‘_Bool’ does not name a type
 extern _Bool atomic_flag_test_and_set_explicit (volatile atomic_flag *,
        ^~~~~
/usr/lib/gcc/arm-linux-gnueabihf/6/include/stdatomic.h:238:41: error: ‘atomic_flag’ does not name a type
 extern void atomic_flag_clear (volatile atomic_flag *);
                                         ^~~~~~~~~~~
/usr/lib/gcc/arm-linux-gnueabihf/6/include/stdatomic.h:240:50: error: ‘atomic_flag’ does not name a type
 extern void atomic_flag_clear_explicit (volatile atomic_flag *, memory_order);
                                                  ^~~~~~~~~~~
atomic_test001.c:5:8: error: ‘_Atomic’ does not name a type
 static _Atomic int myval = 0;
        ^~~~~~~
atomic_test001.c:6:8: error: ‘_Atomic’ does not name a type
 static _Atomic bool flag = true;
        ^~~~~~~
atomic_test001.c: In function ‘int main()’:
atomic_test001.c:9:36: error: ‘myval’ was not declared in this scope
     printf("myval=%d  flag=%d \n", myval, flag);
                                    ^~~~~
atomic_test001.c:9:43: error: ‘flag’ was not declared in this scope
     printf("myval=%d  flag=%d \n", myval, flag);
                                           ^~~~
Kompilierung fehlgeschlagen.

Heater
Posts: 18357
Joined: Tue Jul 17, 2012 3:02 pm

Re: atomic or volatile, that is the question ( Whether 'tis nobler in the mind to mutex them)

Fri Jun 18, 2021 9:40 am

The C++ language is a different language than C. Of course things available in on may not be available in another. C++ is not a supper set of C.

If you want to use C code in a C++ program compile it as C. Use 'extern "C"....' in your C++ code that references it.
https://embeddedartistry.com/blog/2017/ ... -extern-c/

It would probably be wise not to mix use of pthreads into a Qt based program. Qt has it's own threading API, QThread: https://doc.qt.io/qt-5/qthread.html
Last edited by Heater on Fri Jun 18, 2021 9:48 am, edited 2 times in total.
Memory in C++ is a leaky abstraction .

jamesh
Raspberry Pi Engineer & Forum Moderator
Raspberry Pi Engineer & Forum Moderator
Posts: 28990
Joined: Sat Jul 30, 2011 7:41 pm

Re: atomic or volatile, that is the question ( Whether 'tis nobler in the mind to mutex them)

Fri Jun 18, 2021 9:44 am

dsyleixa123 wrote:
Fri Jun 18, 2021 9:21 am
well, I am using multithreading successfully since 10 years and more, all is fine (using volatile + mutexes + thread prios) - I only need to understand atomic which had been suggested, and answers should be suitable for non-professionals, finally the Pi is also for beginners. The answers given by tttapa so far thankfully actually are suitable for beginners (e.g., for me), just missing some details.

Something doesn't make sense here. If you have been writing multithreaded code for 10 years, why do you consider yourself a beginner?

And if you have been using volatile, you've been doing it wrong, as volatile isn't used in multithreaded code. I suspect that your multithreaded code may fail if really stressed.

Yes, the Pi is for beginners, and everyone else, but there are limits to how simple you can make a complicated subject. Multithreaded code is a complicated subject. Avoiding mistakes requires decent knowledge of how it all works, and that can be gained by reading the links provided. If you find some of the terminology difficult, learn that as well.
Principal Software Engineer at Raspberry Pi (Trading) Ltd.
Working in the Application's Team.

dsyleixa123
Posts: 1493
Joined: Mon Jun 11, 2018 11:22 am

Re: atomic or volatile, that is the question ( Whether 'tis nobler in the mind to mutex them)

Fri Jun 18, 2021 9:46 am

I consider myself a beginner at Arduino-hobbyist-level. But back to topic:
@ Heater: I never use QThread, pthread works fine with qt5 so far (we discussed that earlier), but I tried that #ifdef __cplusplus, still same errors:

Code: Select all

#ifdef __cplusplus
extern "C"
{
#endif      
  
#include <stdatomic.h>

#ifdef __cplusplus
}
#endif      

#include <stdbool.h>
#include <stdio.h>

static _Atomic int myval = 1;
static _Atomic bool flag = true;

int main() {
    printf("myval=%d  flag=%d \n", myval, flag);
    myval = 42;
    flag = false;
    myval |= 7;
    printf("myval=%d  flag=%d\n", myval, flag);
}

Code: Select all

g++  -Wall -I/opt/vc/include -o  "atomic_test001" "atomic_test001.c" -pthread -I/opt/vc/include -lshapes -lwiringPi -lpigpio -lrt $(pkg-config eigen3 --cflags) -lreadline  -lArduiPi_OLED (im Verzeichnis: /home/pi/raspiProgs/threadprogs)
In file included from atomic_test001.c:6:0:
/usr/lib/gcc/arm-linux-gnueabihf/6/include/stdatomic.h:40:9: error: ‘_Atomic’ does not name a type
 typedef _Atomic _Bool atomic_bool;
         ^~~~~~~
/usr/lib/gcc/arm-linux-gnueabihf/6/include/stdatomic.h:41:9: error: ‘_Atomic’ does not name a type
 typedef _Atomic char atomic_char;
         ^~~~~~~
/usr/lib/gcc/arm-linux-gnueabihf/6/include/stdatomic.h:42:9: error: ‘_Atomic’ does not name a type
 typedef _Atomic signed char atomic_schar;
         ^~~~~~~
/usr/lib/gcc/arm-linux-gnueabihf/6/include/stdatomic.h:43:9: error: ‘_Atomic’ does not name a type
 typedef _Atomic unsigned char atomic_uchar;
         ^~~~~~~
/usr/lib/gcc/arm-linux-gnueabihf/6/include/stdatomic.h:44:9: error: ‘_Atomic’ does not name a type
 typedef _Atomic short atomic_short;
         ^~~~~~~
/usr/lib/gcc/arm-linux-gnueabihf/6/include/stdatomic.h:45:9: error: ‘_Atomic’ does not name a type
 typedef _Atomic unsigned short atomic_ushort;
         ^~~~~~~
/usr/lib/gcc/arm-linux-gnueabihf/6/include/stdatomic.h:46:9: error: ‘_Atomic’ does not name a type
 typedef _Atomic int atomic_int;
         ^~~~~~~
/usr/lib/gcc/arm-linux-gnueabihf/6/include/stdatomic.h:47:9: error: ‘_Atomic’ does not name a type
 typedef _Atomic unsigned int atomic_uint;
         ^~~~~~~
/usr/lib/gcc/arm-linux-gnueabihf/6/include/stdatomic.h:48:9: error: ‘_Atomic’ does not name a type
 typedef _Atomic long atomic_long;
         ^~~~~~~
/usr/lib/gcc/arm-linux-gnueabihf/6/include/stdatomic.h:49:9: error: ‘_Atomic’ does not name a type
 typedef _Atomic unsigned long atomic_ulong;
         ^~~~~~~
/usr/lib/gcc/arm-linux-gnueabihf/6/include/stdatomic.h:50:9: error: ‘_Atomic’ does not name a type
 typedef _Atomic long long atomic_llong;
         ^~~~~~~
/usr/lib/gcc/arm-linux-gnueabihf/6/include/stdatomic.h:51:9: error: ‘_Atomic’ does not name a type
 typedef _Atomic unsigned long long atomic_ullong;
         ^~~~~~~
/usr/lib/gcc/arm-linux-gnueabihf/6/include/stdatomic.h:52:9: error: ‘_Atomic’ does not name a type
 typedef _Atomic __CHAR16_TYPE__ atomic_char16_t;
         ^~~~~~~
/usr/lib/gcc/arm-linux-gnueabihf/6/include/stdatomic.h:53:9: error: ‘_Atomic’ does not name a type
 typedef _Atomic __CHAR32_TYPE__ atomic_char32_t;
         ^~~~~~~
/usr/lib/gcc/arm-linux-gnueabihf/6/include/stdatomic.h:54:9: error: ‘_Atomic’ does not name a type
 typedef _Atomic __WCHAR_TYPE__ atomic_wchar_t;
         ^~~~~~~
/usr/lib/gcc/arm-linux-gnueabihf/6/include/stdatomic.h:55:9: error: ‘_Atomic’ does not name a type
 typedef _Atomic __INT_LEAST8_TYPE__ atomic_int_least8_t;
         ^~~~~~~
/usr/lib/gcc/arm-linux-gnueabihf/6/include/stdatomic.h:56:9: error: ‘_Atomic’ does not name a type
 typedef _Atomic __UINT_LEAST8_TYPE__ atomic_uint_least8_t;
         ^~~~~~~
/usr/lib/gcc/arm-linux-gnueabihf/6/include/stdatomic.h:57:9: error: ‘_Atomic’ does not name a type
 typedef _Atomic __INT_LEAST16_TYPE__ atomic_int_least16_t;
         ^~~~~~~
/usr/lib/gcc/arm-linux-gnueabihf/6/include/stdatomic.h:58:9: error: ‘_Atomic’ does not name a type
 typedef _Atomic __UINT_LEAST16_TYPE__ atomic_uint_least16_t;
         ^~~~~~~
/usr/lib/gcc/arm-linux-gnueabihf/6/include/stdatomic.h:59:9: error: ‘_Atomic’ does not name a type
 typedef _Atomic __INT_LEAST32_TYPE__ atomic_int_least32_t;
         ^~~~~~~
/usr/lib/gcc/arm-linux-gnueabihf/6/include/stdatomic.h:60:9: error: ‘_Atomic’ does not name a type
 typedef _Atomic __UINT_LEAST32_TYPE__ atomic_uint_least32_t;
         ^~~~~~~
/usr/lib/gcc/arm-linux-gnueabihf/6/include/stdatomic.h:61:9: error: ‘_Atomic’ does not name a type
 typedef _Atomic __INT_LEAST64_TYPE__ atomic_int_least64_t;
         ^~~~~~~
/usr/lib/gcc/arm-linux-gnueabihf/6/include/stdatomic.h:62:9: error: ‘_Atomic’ does not name a type
 typedef _Atomic __UINT_LEAST64_TYPE__ atomic_uint_least64_t;
         ^~~~~~~
/usr/lib/gcc/arm-linux-gnueabihf/6/include/stdatomic.h:63:9: error: ‘_Atomic’ does not name a type
 typedef _Atomic __INT_FAST8_TYPE__ atomic_int_fast8_t;
         ^~~~~~~
/usr/lib/gcc/arm-linux-gnueabihf/6/include/stdatomic.h:64:9: error: ‘_Atomic’ does not name a type
 typedef _Atomic __UINT_FAST8_TYPE__ atomic_uint_fast8_t;
         ^~~~~~~
/usr/lib/gcc/arm-linux-gnueabihf/6/include/stdatomic.h:65:9: error: ‘_Atomic’ does not name a type
 typedef _Atomic __INT_FAST16_TYPE__ atomic_int_fast16_t;
         ^~~~~~~
/usr/lib/gcc/arm-linux-gnueabihf/6/include/stdatomic.h:66:9: error: ‘_Atomic’ does not name a type
 typedef _Atomic __UINT_FAST16_TYPE__ atomic_uint_fast16_t;
         ^~~~~~~
/usr/lib/gcc/arm-linux-gnueabihf/6/include/stdatomic.h:67:9: error: ‘_Atomic’ does not name a type
 typedef _Atomic __INT_FAST32_TYPE__ atomic_int_fast32_t;
         ^~~~~~~
/usr/lib/gcc/arm-linux-gnueabihf/6/include/stdatomic.h:68:9: error: ‘_Atomic’ does not name a type
 typedef _Atomic __UINT_FAST32_TYPE__ atomic_uint_fast32_t;
         ^~~~~~~
/usr/lib/gcc/arm-linux-gnueabihf/6/include/stdatomic.h:69:9: error: ‘_Atomic’ does not name a type
 typedef _Atomic __INT_FAST64_TYPE__ atomic_int_fast64_t;
         ^~~~~~~
/usr/lib/gcc/arm-linux-gnueabihf/6/include/stdatomic.h:70:9: error: ‘_Atomic’ does not name a type
 typedef _Atomic __UINT_FAST64_TYPE__ atomic_uint_fast64_t;
         ^~~~~~~
/usr/lib/gcc/arm-linux-gnueabihf/6/include/stdatomic.h:71:9: error: ‘_Atomic’ does not name a type
 typedef _Atomic __INTPTR_TYPE__ atomic_intptr_t;
         ^~~~~~~
/usr/lib/gcc/arm-linux-gnueabihf/6/include/stdatomic.h:72:9: error: ‘_Atomic’ does not name a type
 typedef _Atomic __UINTPTR_TYPE__ atomic_uintptr_t;
         ^~~~~~~
/usr/lib/gcc/arm-linux-gnueabihf/6/include/stdatomic.h:73:9: error: ‘_Atomic’ does not name a type
 typedef _Atomic __SIZE_TYPE__ atomic_size_t;
         ^~~~~~~
/usr/lib/gcc/arm-linux-gnueabihf/6/include/stdatomic.h:74:9: error: ‘_Atomic’ does not name a type
 typedef _Atomic __PTRDIFF_TYPE__ atomic_ptrdiff_t;
         ^~~~~~~
/usr/lib/gcc/arm-linux-gnueabihf/6/include/stdatomic.h:75:9: error: ‘_Atomic’ does not name a type
 typedef _Atomic __INTMAX_TYPE__ atomic_intmax_t;
         ^~~~~~~
/usr/lib/gcc/arm-linux-gnueabihf/6/include/stdatomic.h:76:9: error: ‘_Atomic’ does not name a type
 typedef _Atomic __UINTMAX_TYPE__ atomic_uintmax_t;
         ^~~~~~~
/usr/lib/gcc/arm-linux-gnueabihf/6/include/stdatomic.h:218:9: error: ‘_Atomic’ does not name a type
 typedef _Atomic struct
         ^~~~~~~
/usr/lib/gcc/arm-linux-gnueabihf/6/include/stdatomic.h:225:3: error: ‘atomic_flag’ does not name a type
 } atomic_flag;
   ^~~~~~~~~~~
/usr/lib/gcc/arm-linux-gnueabihf/6/include/stdatomic.h:230:8: error: ‘_Bool’ does not name a type
 extern _Bool atomic_flag_test_and_set (volatile atomic_flag *);
        ^~~~~
/usr/lib/gcc/arm-linux-gnueabihf/6/include/stdatomic.h:233:8: error: ‘_Bool’ does not name a type
 extern _Bool atomic_flag_test_and_set_explicit (volatile atomic_flag *,
        ^~~~~
/usr/lib/gcc/arm-linux-gnueabihf/6/include/stdatomic.h:238:41: error: ‘atomic_flag’ does not name a type
 extern void atomic_flag_clear (volatile atomic_flag *);
                                         ^~~~~~~~~~~
/usr/lib/gcc/arm-linux-gnueabihf/6/include/stdatomic.h:240:50: error: ‘atomic_flag’ does not name a type
 extern void atomic_flag_clear_explicit (volatile atomic_flag *, memory_order);
                                                  ^~~~~~~~~~~
atomic_test001.c:15:8: error: ‘_Atomic’ does not name a type
 static _Atomic int myval = 1;
        ^~~~~~~
atomic_test001.c:16:8: error: ‘_Atomic’ does not name a type
 static _Atomic bool flag = true;
        ^~~~~~~
atomic_test001.c: In function ‘int main()’:
atomic_test001.c:19:36: error: ‘myval’ was not declared in this scope
     printf("myval=%d  flag=%d \n", myval, flag);
                                    ^~~~~
atomic_test001.c:19:43: error: ‘flag’ was not declared in this scope
     printf("myval=%d  flag=%d \n", myval, flag);
                                           ^~~~
Kompilierung fehlgeschlagen.

Heater
Posts: 18357
Joined: Tue Jul 17, 2012 3:02 pm

Re: atomic or volatile, that is the question ( Whether 'tis nobler in the mind to mutex them)

Fri Jun 18, 2021 9:55 am

dsyleixa123 wrote:
Fri Jun 18, 2021 9:46 am
@ Heater: I tried that, same errors:
Of course, you are still compiling all your code as C++, by using g++.

You need to move all the code that uses C features out of main into a function or functions in a .c file. Have a header file for that .c file. Use the 'extern "C'..' as suggested in the link I gave.
Memory in C++ is a leaky abstraction .

dsyleixa123
Posts: 1493
Joined: Mon Jun 11, 2018 11:22 am

Re: atomic or volatile, that is the question ( Whether 'tis nobler in the mind to mutex them)

Fri Jun 18, 2021 9:56 am

update,
also this version don't work (same errors):

Code: Select all

#include <stdbool.h>
#include <stdio.h>

#ifdef __cplusplus
extern "C"
{
#endif      
  
#include <stdatomic.h>

static _Atomic int myval = 1;
static _Atomic bool flag = true;

#ifdef __cplusplus
}
#endif      




int main() {
    printf("myval=%d  flag=%d \n", myval, flag);
    myval = 42;
    flag = false;
    myval |= 7;
    printf("myval=%d  flag=%d\n", myval, flag);
}

dsyleixa123
Posts: 1493
Joined: Mon Jun 11, 2018 11:22 am

Re: atomic or volatile, that is the question ( Whether 'tis nobler in the mind to mutex them)

Fri Jun 18, 2021 9:58 am

ah, ok, cross-over-posting, I see, but that would be too complicated with extra .c files.

How to make my atomic test code compatible both for C and C++, all in 1, without external .c files?

Heater
Posts: 18357
Joined: Tue Jul 17, 2012 3:02 pm

Re: atomic or volatile, that is the question ( Whether 'tis nobler in the mind to mutex them)

Fri Jun 18, 2021 10:09 am

I would strongly advise against doing that. Mixing two languages in a single source file is a mess.

Actually, I don't think it's even possible. In any nice way at least.

You could probably move all your C code into it's own part of a source file and all the C++ into another. Then use "#ifdef __cplusplus", "#ifndef __cplusplus" and `extern "C"" around things. Then you could compile that source file twice, once as C and once as C++. Then link the two resulting object files. Be sure your "main()" is only copied in one side or the other, preferably the C++ side.

No really, don't do this.

EDIT: No wait: What you are asking is impossible. The C code in question that you want to make "compatible both for C and C++, all in 1, without external .c files?" uses features only available in C. That is all the stuff in stdatomic.h.

At least I think so. Anyone know better?
Memory in C++ is a leaky abstraction .

dsyleixa123
Posts: 1493
Joined: Mon Jun 11, 2018 11:22 am

Re: atomic or volatile, that is the question ( Whether 'tis nobler in the mind to mutex them)

Fri Jun 18, 2021 10:20 am

thanks, but I always use just Geany for my non-GUI-apps and qt5 creator for my GUI-apps, always having just 1 file to compile in 1 go and no makefiles at all.
Perhaps tttapa or other professional programmers have suggestions about a completely new atomic code which is both C and C++ compatible out of the box?
(e.g. sort of cross-platform-compatible "atomic" sub-data-type, useable like "static" or "volatile" additionally to basic primitive data types such as
int i;
volatile int i;
static int i;
volatile static int i;
atomic int i;
static atomic int i; )

User avatar
jahboater
Posts: 7176
Joined: Wed Feb 04, 2015 6:38 pm
Location: Wonderful West Dorset

Re: atomic or volatile, that is the question ( Whether 'tis nobler in the mind to mutex them)

Fri Jun 18, 2021 10:32 am

dsyleixa123 wrote:
Fri Jun 18, 2021 8:01 am
c-standard-documents - 99.9999% is exaggerated unspecific and verbose talk in technical terms and terminologies overloaded and overwhelmed with unnecessary and ambiguous data.
Apart from using technical terms, none of that statement is true. The exact opposite in fact.

The ISO standards documents are very carefully written by a large group of people over a period of several years, then reviewed over and over again.
It takes approximately 10 years to prepare each new C standard.

These documents are really the only complete and definitive source of information about the language.
This is especially true of C++ where there is no single published book that I know of that includes the entire language, whereas the standard obviously does.

The standards are obviously "definitive".
They state precisely what should happen, and if a compiler does something else, then its a bug and should be reported.
dsyleixa123 wrote:
Fri Jun 18, 2021 8:01 am
need exact answers to specific questions
The ISO standards are the place for that.

Its worth spending the time getting familiar with them, they are quite easy to read with a little practice.
They are well indexed and compared to a book it is (relatively) easy to find specific information.

Books include other information, with more time spent explaining the reasons for things and try to help beginners understand stuff.
All of which is good.
Last edited by jahboater on Fri Jun 18, 2021 10:35 am, edited 1 time in total.

dsyleixa123
Posts: 1493
Joined: Mon Jun 11, 2018 11:22 am

Re: atomic or volatile, that is the question ( Whether 'tis nobler in the mind to mutex them)

Fri Jun 18, 2021 10:35 am

thanks, sort of that is repeating what meanwhile had been stated several times by other posters but does not help anything either.
Finally and fortunately a basic example is already working (if only for gcc, not for g++ unfortunately).
viewtopic.php?p=1879129#p1879129

Perhaps tttapa or other professional programmers have beginner-friendly suggestions about a completely new atomic code which is both C and C++ compatible out of the box?

Heater
Posts: 18357
Joined: Tue Jul 17, 2012 3:02 pm

Re: atomic or volatile, that is the question ( Whether 'tis nobler in the mind to mutex them)

Fri Jun 18, 2021 11:03 am

dsyleixa123 wrote:
Fri Jun 18, 2021 10:35 am
thanks, sort of that is repeating what meanwhile had been stated several times by other posters but does not help anything either.
Finally and fortunately a basic example is already working (if only for gcc, not for g++ unfortunately).
viewtopic.php?p=1879129#p1879129

Perhaps tttapa or other professional programmers have beginner-friendly suggestions about a completely new atomic code which is both C and C++ compatible out of the box?
The beginner friendly suggestions have been made here, repeatedly. Using threads and atomics across two different languages is hardly a beginner friendly topic. Professionals would not even consider trying it.
Memory in C++ is a leaky abstraction .

dsyleixa123
Posts: 1493
Joined: Mon Jun 11, 2018 11:22 am

Re: atomic or volatile, that is the question ( Whether 'tis nobler in the mind to mutex them)

Fri Jun 18, 2021 11:12 am

Heater, you stated already by yourself:
At least I think so. Anyone know better?
so let's just wait if anyone knows better, ok?

User avatar
rpdom
Posts: 18865
Joined: Sun May 06, 2012 5:17 am
Location: Chelmsford, Essex, UK

Re: atomic or volatile, that is the question ( Whether 'tis nobler in the mind to mutex them)

Fri Jun 18, 2021 11:55 am

dsyleixa123 wrote:
Fri Jun 18, 2021 11:12 am
Heater, you stated already by yourself:
At least I think so. Anyone know better?
so let's just wait if anyone knows better, ok?
Many people have already stated (or implied) that what you are trying to do is NOT a beginner subject. In fact most professionals wouldn't do it like that.

You keep claiming to be a beginner with 10+ years experience. If that is true you either are no longer a beginner and we shouldn't treat you like one, or you haven't learned anything in all that time and we're wasting our time here.

Please at least TRY reading the links given. If you do that and find parts of it hard to follow then people will try to help. But just saying "that's too difficult for me" is not going to make any friends here.
Unreadable squiggle

dsyleixa123
Posts: 1493
Joined: Mon Jun 11, 2018 11:22 am

Re: atomic or volatile, that is the question ( Whether 'tis nobler in the mind to mutex them)

Fri Jun 18, 2021 11:59 am

yes, I meanwhile even read some of the links, and searching through them by different keywords, but no one writes something about atomic both C and C++ compatibility which is now the question.
So far only Heater stated that he doesn't know a compatible solution.
Thank you for stating that you also don't know a compatible solution but perhaps someone else knows one?

tttapa
Posts: 65
Joined: Mon Apr 06, 2020 2:52 pm

Re: atomic or volatile, that is the question ( Whether 'tis nobler in the mind to mutex them)

Fri Jun 18, 2021 12:23 pm

dsyleixa123 wrote:
Fri Jun 18, 2021 9:21 am
using volatile + mutexes + thread prios
As stated by myself and others, do not use volatile for multithreading.

I have not much to add to what has already been said:
Trying to come up with a solution that allows you to compile your code with both a C and a C++ compiler is a waste of time in my opinion. If you are using Qt with C++, use C++ atomics. If you really want to use C atomics (why?), you'll have to write separate .c files that you compile with a C compiler and that you could couple to your C++ code using an “extern C” API.
It's pointless to write “C code” and then compile it with g++. As others have said, although there's some overlap, C and C++ are different languages, if you use a C++ compiler, you have to write C++ code, and if you use a C compiler, you write C code.

This thread is turning into a repetition of the same advice by different people, and it seems to go in one ear and out the other.

Atomics is not an easy topic, if you want to use them, you have to learn how to use them correctly, e.g. by reading/watching the links I provided.
To paraphrase Euclid: There is no royal road to computer science.

FWIW, it looks like they're planning to standardize _Atomic(T) in C++23 for compatibility with C: https://en.cppreference.com/w/cpp/atomic/atomic
Implementations are recommended to ensure that the representation of _Atomic(T) in C is same as that of std::atomic<T> in C++ for every possible type T. The mechanisms used to ensure atomicity and memory ordering should be compatible.

dsyleixa123
Posts: 1493
Joined: Mon Jun 11, 2018 11:22 am

Re: atomic or volatile, that is the question ( Whether 'tis nobler in the mind to mutex them)

Fri Jun 18, 2021 12:30 pm

ok, if no other one is coming up with a compatible solution then unfortunately I have to be content with a second-class solution.
But as stated, I meanwhile even read through some of your links, and searching through them by different keywords, but no one writes something about atomic both C and C++ compatibility which is now the question.
I tried meanwhile sth more by myself, but even this failed to compile:

Code: Select all

#ifdef __cplusplus
#include <atomic>
using namespace std;
#else
#include <stdatomic.h>
#endif

static  atomic_int myval = 1;
static  atomic_bool flag = true;
so I'll abandon that.
A pity that C and C++ don't provide yet compatible atomic data types though, just like for static and for volatile.

(edit, typos)
Last edited by dsyleixa123 on Sun Jun 20, 2021 9:37 am, edited 2 times in total.

Heater
Posts: 18357
Joined: Tue Jul 17, 2012 3:02 pm

Re: atomic or volatile, that is the question ( Whether 'tis nobler in the mind to mutex them)

Fri Jun 18, 2021 12:40 pm

dsyleixa123 wrote:
Fri Jun 18, 2021 11:59 am
yes, I meanwhile even read some of the links, and searching through them by different keywords, but no one writes something about atomic both C and C++ compatibility which is now the question.
So far only Heater stated that he doesn't know a compatible solution.
Thank you for stating that you also don't know a compatible solution but perhaps someone else knows one?
Or perhaps there isn't one. Or at least not one any sane programmer would try and use.

As we are using C and and C++ here of course it can be done. For example one could write a module that compiles with both C and C++ (that is only using the subset of language features that are common to C and C++) and do all the atomic operations using in-line assembler. Making use of whatever atomic instructions ones processor has.

For example x86 has a "lock" prefix byte one can use in front of exchange instructions (XCHG), compare-exchange (CMPXCHG) and so on. The lock prefix ensures that the following instruction is performed atomically, no other thread/processor can make an access to the data. in question while some other thread/processor is executing an instruction with a lock.
See how to do this here:https://courses.cs.washington.edu/cours ... ations.pdf

Of course having done that ones code is processor architecture and compiler dependent. You would have to reimplement all that assembler for use on ARM and so on. So not a nice idea.
Memory in C++ is a leaky abstraction .


Heater
Posts: 18357
Joined: Tue Jul 17, 2012 3:02 pm

Re: atomic or volatile, that is the question ( Whether 'tis nobler in the mind to mutex them)

Fri Jun 18, 2021 12:49 pm

I just found this brilliant website on the topic of volatile and threads. It's short and extremely clear and simple. 100% beginner friendly:
http://isvolatileusefulwiththreads.com/

Made me laugh, after all this discussion.
Memory in C++ is a leaky abstraction .

tttapa
Posts: 65
Joined: Mon Apr 06, 2020 2:52 pm

Re: atomic or volatile, that is the question ( Whether 'tis nobler in the mind to mutex them)

Fri Jun 18, 2021 12:52 pm

dsyleixa123 wrote: but no one writes something about atomic both C and C++ compatibility which is now the question.
That should tell you something about the approach you seem to be stuck on ...
dsyleixa123 wrote: A pity that C and C++ don't provide yet compatible atomic data types though, just like for static and for volatile.
They are compatible in the sense that you can pass a pointer to an `std::atomic<int>` in C++ to a C function that expects an `_Atomic(int)`. They are not compatible in the sense that you can just write actual code that can be compiled by both a C compiler and a C++ compiler, that would be pointless, you either write C code or C++ code, why would you compile the same code twice with a different compiler? (Apart from declarations in header files, of course, where you still have to use some #ifdef __cplusplus hacks.)

You wouldn't expect code with `std::vector<int>` or `QString` to compile when using a C compiler, so why would you expect atomics to be any different?

It's still unclear to me why you're so focused on having your code compatible with both C and C++, unless you have a very good reason to do so, it's a waste of time. If you do have a good reason, please let us know, and we might be able to come up with something.
Heater wrote: I just found this brilliant website on the topic of volatile and threads. It's short and extremely clear and simple. 100% beginner friendly:
http://isvolatileusefulwiththreads.com/

Made me laugh, after all this discussion.
:D

dsyleixa123
Posts: 1493
Joined: Mon Jun 11, 2018 11:22 am

Re: atomic or volatile, that is the question ( Whether 'tis nobler in the mind to mutex them)

Fri Jun 18, 2021 12:53 pm

yes, funny, but it also doesn't say anything about atomic C and C++ compatibility (like for keywords static or volatile).
It's still unclear to me why you're so focused on having your code compatible with both C and C++
I don't want to use and handle classes for that purpose and keep all like straight-C and compatible to it as even possible (KISS).
But as stated I'll abandon that. Probably at least until '23.

Heater
Posts: 18357
Joined: Tue Jul 17, 2012 3:02 pm

Re: atomic or volatile, that is the question ( Whether 'tis nobler in the mind to mutex them)

Fri Jun 18, 2021 5:14 pm

dsyleixa123 wrote:
Fri Jun 18, 2021 12:53 pm
But as stated I'll abandon that. Probably at least until '23.
What happens in 23?

I see no signs that either C or C++ standards will move towards convergence in this area with up an coming standards revisions.
Memory in C++ is a leaky abstraction .

dsyleixa123
Posts: 1493
Joined: Mon Jun 11, 2018 11:22 am

Re: atomic or volatile, that is the question ( Whether 'tis nobler in the mind to mutex them)

Fri Jun 18, 2021 5:16 pm

well, I admit I may have misunderstood tttapa's post (poor English, remember?)

tttapa
Posts: 65
Joined: Mon Apr 06, 2020 2:52 pm

Re: atomic or volatile, that is the question ( Whether 'tis nobler in the mind to mutex them)

Fri Jun 18, 2021 5:32 pm

I referred to this section in en.cppreference.com/w/cpp/atomic/atomic:
(since C++23)
The compatibility macro _Atomic is provided in <stdatomic.h> such that _Atomic(T) is identical to std::atomic<T> while both are well-formed.
It'll allow you to use C header files that contain declarations of _Atomic variables, arguments or return types in C++ code, but it still doesn't necessarily allow you to write code with that's valid C and C++ at the same time (which is pointless IMO).

Return to “C/C++”