- Thread-safe initialization of static objects - 16 Updates
- Problem with calling C++ from Fortran - 9 Updates
"Chris M. Thomasson" <chris.m.thomasson.1@gmail.com>: Sep 09 07:30PM -0700 On 9/9/2023 11:00 AM, Pavel wrote: > time but I would at least try to implement call_once with a critical > section (whose creation, contrary to OP's insinuations, cannot fail > since Windows Vista). Windows has: https://learn.microsoft.com/en-us/windows/win32/api/synchapi/nf-synchapi-initonceexecuteonce https://learn.microsoft.com/en-us/windows/win32/api/synchapi/nf-synchapi-initonceinitialize This is their part of their "futex" API: https://learn.microsoft.com/en-us/windows/win32/api/synchapi/nf-synchapi-waitonaddress |
Bonita Montero <Bonita.Montero@gmail.com>: Sep 10 10:57AM +0200 Am 09.09.2023 um 22:37 schrieb Richard Damon: > The Standard defines the final results that must happen > (or possibilities that can happen in some cases). The standards also should consider side effects as in this example when a static initialization would fail because of a synchronization error. |
Bonita Montero <Bonita.Montero@gmail.com>: Sep 10 10:58AM +0200 Am 09.09.2023 um 21:59 schrieb Chris M. Thomasson: > An address based hash into a table based approach works by creating > everything up front. If this fails, then the user program logic is > not even executed at all. Do you want to follow in Amine's footsteps ? |
Bonita Montero <Bonita.Montero@gmail.com>: Sep 10 10:59AM +0200 Am 09.09.2023 um 22:41 schrieb Richard Damon: > Why? Because the standard should honour that kernel-synch might fail on static initialization. |
Richard Damon <Richard@Damon-Family.org>: Sep 10 06:51AM -0700 On 9/10/23 1:57 AM, Bonita Montero wrote: > The standards also should consider side effects as in this example > when a static initialization would fail because of a synchronization > error. You don't seem to understand that sincd it CAN be done in a way that always works, any method that doesn't always work is just WRONG and non-conforming. I guess you think that 1 + 1 must be allowed to be 1 in case of "synchronization errors". Static Initialization has DEFINED behavior, and that behavior must be honored, and the implementation do what is need to make that happen. Methods have been shown to do it (perhaps less performant than this is some conditions), so it is possible, so you can't say the Standard is asking for impossible behavior, thus any "optimizations" that don't meet that defined behavior are just WRONG. Saying something wrong must be made right is just WRONG, so you are WRONG in your claim. PERIOD. |
Bonita Montero <Bonita.Montero@gmail.com>: Sep 10 05:46PM +0200 Am 10.09.2023 um 15:51 schrieb Richard Damon: > You don't seem to understand that sincd it CAN be done in a way that > always works, ... A standard shouldn't mandate that this never fails. > Static Initialization has DEFINED behavior, and that behavior must be > honored, and the implementation do what is need to make that happen. Locking-errors while static initialitation are unspecified; whether they might occur or not on a specific operating system doesn't matter. |
Paavo Helde <eesnimi@osa.pri.ee>: Sep 10 07:08PM +0300 10.09.2023 18:46 Bonita Montero kirjutas: >> You don't seem to understand that sincd it CAN be done in a way that >> always works, ... > A standard shouldn't mandate that this never fails. So suppose the standard committee agrees with you and adds a sentence to the standard: Dynamic initialization of a non-local variable with static storage duration can fail even if its initializing function does not throw, in which case the behavior is ...undefined... / ..unspecified... / ...calling std::terminate() after unspecified time... Which variant do you prefer? And how would this help the programmer who needs to write programs in C++? Should they just avoid creating any static variables at all, in order to not trigger this failure scenario? |
Bonita Montero <Bonita.Montero@gmail.com>: Sep 10 06:15PM +0200 Am 10.09.2023 um 18:08 schrieb Paavo Helde: > Which variant do you prefer? And how would this help the programmer who > needs to write programs in C++? Should they just avoid creating any > static variables at all, in order to not trigger this failure scenario? It should be handled like synchronization on a std::mutex, which can fail with a system_error. If this would happen the object would remain uninitialized. |
Richard Damon <Richard@Damon-Family.org>: Sep 10 09:32AM -0700 On 9/10/23 8:46 AM, Bonita Montero wrote: >> You don't seem to understand that sincd it CAN be done in a way that >> always works, ... > A standard shouldn't mandate that this never fails. You WANT a standard that says even if your program is written totally correct, the implementation can decide that it will just make it run wrong? >> honored, and the implementation do what is need to make that happen. > Locking-errors while static initialitation are unspecified; whether > they might occur or not on a specific operating system doesn't matter. Since it has been shown that with a simpler locking method, you can ALWAYS succeed (or die with a resource error before starting user code), not meeting the requirement is just an error in the implementation. PERIOD. ANY operating system that can correctly run multi-threaded code can handle that. If it can't, it can't actually handle multi-threaded code. If an "optimization" can cause failures that can't otherwise occur, and are not allowed by the standard, then that "optimization" isn't allowed (except by switching to a non-conforming mode). You don't seem to understand what a "Standard" is. |
"Chris M. Thomasson" <chris.m.thomasson.1@gmail.com>: Sep 10 11:05AM -0700 On 9/10/2023 1:58 AM, Bonita Montero wrote: >> everything up front. If this fails, then the user program logic is >> not even executed at all. > Do you want to follow in Amine's footsteps ? What do you mean by that comment? |
"Chris M. Thomasson" <chris.m.thomasson.1@gmail.com>: Sep 10 11:08AM -0700 On 9/10/2023 1:58 AM, Bonita Montero wrote: >> everything up front. If this fails, then the user program logic is >> not even executed at all. > Do you want to follow in Amine's footsteps ? Iirc, some systems have a large table of mutexes or semaphores created up front in the kernel itself. They use them for contended futexes to wait on. A futex is address based, and when they have to block that index the address into said table. Have you ever used them before? Also, think of Windows keyed events. |
"Chris M. Thomasson" <chris.m.thomasson.1@gmail.com>: Sep 10 11:09AM -0700 On 9/10/2023 1:59 AM, Bonita Montero wrote: >> Why? > Because the standard should honour that kernel-synch might fail > on static initialization. Strange answer. Humm... |
"Chris M. Thomasson" <chris.m.thomasson.1@gmail.com>: Sep 10 11:12AM -0700 On 9/10/2023 1:59 AM, Bonita Montero wrote: >> Why? > Because the standard should honour that kernel-synch might fail > on static initialization. So, are you suggesting that the C++ standard should be tightly integrated with a given kernel impl? Humm... Strange. POSIX aside for a moment... |
"Chris M. Thomasson" <chris.m.thomasson.1@gmail.com>: Sep 10 11:12AM -0700 On 9/10/2023 1:57 AM, Bonita Montero wrote: > The standards also should consider side effects as in this example > when a static initialization would fail because of a synchronization > error. What error? |
"Chris M. Thomasson" <chris.m.thomasson.1@gmail.com>: Sep 10 11:13AM -0700 On 9/10/2023 9:15 AM, Bonita Montero wrote: > It should be handled like synchronization on a std::mutex, > which can fail with a system_error. If this would happen > the object would remain uninitialized. then what? |
"Chris M. Thomasson" <chris.m.thomasson.1@gmail.com>: Sep 10 11:14AM -0700 On 9/10/2023 9:32 AM, Richard Damon wrote: > are not allowed by the standard, then that "optimization" isn't allowed > (except by switching to a non-conforming mode). > You don't seem to understand what a "Standard" is. Ditto. |
db <dieterhansbritz@gmail.com>: Sep 10 02:33PM +0200 > If your knowledge of C++ syntax is so basic you don't know which bits go > where I'd suggest getting someone else to write the C++ code and you stick > to fortran. An unhelpful comment.. The C++ function was written by an experienced C++ programmer, and my problem is calling it from Fortran. OK, I missed the extra opening {. The problem lies in the communication between Fortran and C++. -- Dieter Britz |
db <dieterhansbritz@gmail.com>: Sep 10 02:36PM +0200 On 09.09.2023 15.56, Paavo Helde wrote: >> [...] > This is a fortran error message. It's not very likely you will get any > help about this here, most people here do not know anything about fortran. I have tried that but so far no one was able to help there, so I thought I'd try at the other end. No go here either. Ar well, I might have to myself translate the C++ code into Fortran. I have done that with another routine and it was quite laborious. -- Dieter Britz |
db <dieterhansbritz@gmail.com>: Sep 10 02:48PM +0200 > : > } > } Where should this go in the code? I added it at the end as is, and now I get this: ~/ownlib90/tests> ./jbandtest jband.cpp:88:1: error: expected initializer before 'extern' 88 | extern "C" { | ^~~~~~ jband.cpp:96:1: error: expected unqualified-id before '{' token 96 | { | ^ jband.cpp: In function 'void calledFromFortran()': jband.cpp:350:9: error: expected primary-expression before ':' token 350 | : ... -- Dieter Britz |
Ben Bacarisse <ben.usenet@bsb.me.uk>: Sep 10 02:22PM +0100 > jband.cpp:350:9: error: expected primary-expression before ':' token > 350 | : > ... You are giving people very little to go on. There's an unknown command (./jbandtest) the gives some errors where only one line of code can be seen. Can you produce a cut-down version to the program that shows the same error -- mimimal example of the C++ and of the Fortran that should calls it but which fails? That would mean you could post the code. If that is not possible, can you link to the source so those who know both C++ and Fortran can take a proper look? -- Ben. |
Bo Persson <bo@bo-persson.se>: Sep 10 04:08PM +0200 On 2023-09-09 at 12:52, db wrote: > jband.cpp:88:1: error: expected initializer before 'extern' > 88 | extern "C" { > | ^~~~~~ I wild guess here is that the line *before* this is where something is missing. The message is just that 'extern' was not expected here, but something else. |
Michael S <already5chosen@yahoo.com>: Sep 10 08:38AM -0700 On Saturday, September 9, 2023 at 11:54:53 AM UTC+3, db wrote: > end function FORTJBAND > I run this using this script > g++ -o jband.o jband.cpp That's command is wrong. Should be: g++ -c -o jband.o jband.cpp |
Paavo Helde <eesnimi@osa.pri.ee>: Sep 10 06:49PM +0300 10.09.2023 15:33 db kirjutas: > programmer, and my problem is calling it from Fortran. > OK, I missed the extra opening {. The problem lies > in the communication between Fortran and C++. From C++ side it's necessary to declare and compile the function extern "C" and it must be exported from the resulting shared library (by __declspec(dllexport) or __attribute__ ((visibility ("default"))), depending on the platform). For sure an experienced C++ programmer is able to do that easily. After that, the ball is on the Fortran side. |
Ben Bacarisse <ben.usenet@bsb.me.uk>: Sep 10 05:27PM +0100 > Can you produce a cut-down version to the program that shows the same > error -- mimimal example of the C++ and of the Fortran that should > calls it but which fails? That would mean you could post the code. I see you have indeed posted half of it. If you post the C++ source, someone might be able to help with both parts. I can tell you a bit about what's wrong with the Fortran you posted, but I need to see the other half. -- Ben. |
Michael S <already5chosen@yahoo.com>: Sep 10 09:51AM -0700 On Saturday, September 9, 2023 at 11:54:53 AM UTC+3, db wrote: > Any ideas? > -- > Dieter Britz I manged to pass link. 99% of the problems appear to have nothing to do with C++ language. It's partly bad Fortran, partly wrong size of floating-point types and partly forgotten -c flag in compilation commands. That's my Fortran (f90) source code: module STUFF integer, parameter :: dbl=selected_real_kind(14) integer, parameter :: qud=selected_real_kind(30) end module STUFF module abc use, intrinsic :: iso_c_binding interface function JBAND (tbar) bind(c) import c_long_double real(c_long_double) :: JBAND real(c_long_double) :: tbar end function JBAND end interface end module abc function FORTJBAND (tbar) use STUFF; use abc; implicit none real(dbl) :: FORTJBAND real(qud) :: tbar real(10) :: tbar10 real(10) :: res10 tbar10 = tbar res10 = JBAND (tbar10) FORTJBAND = res10 end function FORTJBAND program JBAND_TEST use STUFF; implicit none real(dbl) :: curr, FORTJBAND real(qud) :: tbar do read *, tbar if (tbar < 0) exit curr = FORTJBAND (tbar) print '(" curr =", f10.4)', curr enddo end program JBAND_TEST That's my C++ source code (1 line) extern "C" long double jband(long double x) { return x; } That's my compilation commands: g++ -c -o jband.o jband.cpp gfortran -c -o jbandtest.o jbandtest.f90 gfortran jband.o jbandtest.o Now I have no idea if it works like intended or not |
You received this digest because you're subscribed to updates for this group. You can change your settings on the group membership page. To unsubscribe from this group and stop receiving emails from it send an email to comp.lang.c+++unsubscribe@googlegroups.com. |
No comments:
Post a Comment