Random global variable

Hi,

I would like to create a global variable (outside main()) with an random value inside it. Anyway, it doesn 't work with srand() and rand(). Does anybody known how to do ? thanks
Last edited on
Can you show us your code? You could declare a global variable and initialize it from another function/main function.
You need a random generator:

1
2
3
4
5
6
template <typename IntegerT>
IntegerT random( IntegerT min, IntegerT max )
{
  static std::ranlux48 rng( std::chono::system_clock().now().time_since_epoch().count() );
  return std::uniform_int_distribution <T> ( min, max )( rng );
}

Now you can feel free to initialize it whenever:

 
int foo = random <int> ( 1, 100 );

I don’t think this should run afoul of any SIOF problems.

Good luck!

[edit]
Oh, yeah:

1
2
#include <chrono>
#include <random> 
Last edited on
I don’t think this should run afoul of any SIOF problems.
When you don't think so, why do you mention it?
If the implementation supports Library Fundamentals TS v2 (ISO/IEC TS 19568:2017)

1
2
3
4
5
6
7
8
9
10
11
12
13
#include <iostream>
#include <experimental/random> // Library Fundamentals v2

// generates a random integer in [100,999]
// uses a per-thread object of type std::uniform_int_distribution<int>
// and a per-thread object of type std::default_random_engine initialised to an "unpredictable" state
// https://en.cppreference.com/w/cpp/experimental/randint
const int random_value = std::experimental::randint( 100, 999 );
 
int main()
{
    std::cout << "random value: " << random_value << '\n';
}

http://coliru.stacked-crooked.com/a/7c3dc137b19338cc
MikeStgt wrote:
I don’t think this should run afoul of any SIOF problems.
When you don't think so, why do you mention it?

Because I could be wrong.
Because I could be wrong.
That is not material, the point is, where do you see the remote chance for a Static Initialization Order Fiasco?
MikeStgt wrote:
That is not material, the point is [SOIF can’t happen]


It is entirely material, because initialization of global variables has the potential for SOIF with system objects, like whatever the system clock may do behind the scenes.

I still think it unlikely that system clock is doing anything behind the scenes that will cause an issue, but as the possibility exists, it is fair to mention it.

It is also fully in context. You asked about my assessment. You did not ask about the validity of the SOIF issue. Expect answers to match your questions.
You did not ask about the validity of the SOIF issue.
After your incommensurate derailment recently ( http://www.cplusplus.com/forum/general/251744/2/#msg1108545 ) you could have perceived, that I am not interested in estimations. So when I ask "Why?" I'd simply like to know about the facts of SOIF in this case.

What I found so far about SOIF are those anwers to FAQ here: http://parashift.com/c++-faq/static-init-order.html
There my attention was attracted by this hint:
Note: The static initialization order problem can also, in some cases, apply to built-in/intrinsic types.
Is it this what could cause an issue with your code? Or something else?
> I'd simply like to know about the facts of SOIF in this case.

There is no static initialisation order problem with the code under discussion.
For details, see: http://eel.is/c++draft/res.on.data.races
and https://en.cppreference.com/w/cpp/language/storage_duration#Static_local_variables (C++11)
Thank you for the links.
So may I conclude, there is no SOIF possible in this case, because there is for sure neither recursion nor multiple threads [that] attempt to initialize the same static local variable concurrently?
Because there is no recursive entry into the block, there is no race condition even if multiple threads attempt to initialise the same static local variable concurrently (C++11).
@MikeStgt
You are an ass. Almost everything that comes out of you is crap. And I am so fracking sick of the strawman BS and personal attacks you are constantly levelling against me. Go away and leave me alone. I will no longer be responding to you directly, but when you follow me around the forum to pull bullcrap, I am going to remind everyone that you are harassing me and therefore won’t be answering you.

@JLBorges
Unless I am misunderstanding you, I don’t think those apply.

There is no SOIF issue with my random<>() function. (Precisely because of the stuff you linked.)

The issue is that it is being called (and, hence, the internal objects in the function are being initialized) at the same time as the global int foo. So if system clock is doing something that isn’t guaranteed to be initialized before entry to main(), then SOIF is an issue.

That said, the only real offender I am aware of with the standard library has been (before C++11) the standard iostreams (cin, cout, cerr), and the fix was to add a magically-named object to the head of every file that #includes <iostream>, so that it is initialized first (guaranteed by the initialization order of global objects in the same translation unit) and consequently invoke the global standard iostream init() function — all before anything else at the global-initialization stage of application startup can try to use any of them.

AFAIK, C++ compilers are otherwise under no obligation to make sure that all the language’s utilities are properly functional when the .init section is being traipsed.

Again, I don’t actually think there is an issue here.

But I do think there could be.

But I also could be wrong.


If OP were to run my code on his compiler and discover that something fails... SOIF would be the first thing to suspect.

Correct me if I am wrong. You tend to have a better grasp on these things than I do.
@Duthomhas (11512)
What's wrong? Could you please focus on the subject. I asked polite and see no reason on my side that could allow you to be so impudent. I am absolutely not interested in "personal attacks you are constantly levelling against me" as you claim. I am here to learn about C++, for sure I am not here because of you. What an illusion.


Again, I don’t actually think there is an issue here.

But I do think there could be.


And as I am a novice, I dared to ask questions.
@JLBorges
there is no race condition even if multiple threads attempt to initialise the same static local variable concurrently
Uh! Just hoped to have learned something new, alas the "even if" in your explanation destroyed the hope instantly.

Up to now my only experience with threads is from ooREXX. There a special method is required "tunnelling" content of variables between threads. But local variables are thread-local. Exist techniques in C++ that ensure different threads will see the same content of a local variable?
> the "even if" in your explanation destroyed the hope instantly.

Re. dynamic initialisation of a static local variable:
It is the responsibility of the implementation to ensure that there are no data races.

For an example, see the code generated for:
1
2
3
4
5
6
7
int foo() noexcept ;

int bar()
{
    static int n = foo() ;
    return ++n ;
}

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


> Exist techniques in C++ that ensure different threads will see the same content of a local variable?

Atomic objects: https://en.cppreference.com/w/cpp/atomic
Synchronisation primitives eg. std::mutex: https://en.cppreference.com/w/cpp/thread/mutex
Thank you for the links, alas the first one -- oops, just tried again, now it works.

Little subject drift... Atomic objects: offers lockless concurrent programming -- IMO it could serve as base for Pipelines, https://en.wikipedia.org/wiki/CMS_Pipelines
I do miss something adequate mature for PCs.
thank you for all the replies.
My problem was i do srand() not in the main fonction. So it doesn 't work
Last edited on
It would work just fine if you had tried the function I gave you.

But since you changed your requirements to being C-compatible, here you go.

1
2
3
4
#include <iso646.h>
#include <stdbool.h>
#include <stdlib.h>
#include <time.h> 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
int random( int min, int max )
{
  static bool is_initialized = false;
  if (!is_initialized)
  {
    srand( time( NULL ) );
    is_initialized = true;
  }

  int result;
  do result = rand();
  while ((result < min) and (result > max));
  return result;
}
 
int foo = random( 1, 100 );

Same (potential) caveat applies; same (near zero) likelihood probability of issue exists; AFAIK, no known implementation will be problematic.
Topic archived. No new replies allowed.