When was random() introduced in C and why does standard 89 not recognise it?

128 Views Asked by At

I’m working on a Operating Systems project with requirements being the usage of C89 and pedantic flags.

Since I am on macOS, I’ve encountered a fair amount of issues with the rand() function during a few exercises. In fact, its macOS man page calls it a “bad number generator”. So, to avoid issues with it I had switched to using random(). Now, since I am compiling with -std=c89, -pedantic, wall and werror, it refuses to function correctly due to having a warning about an implicit declaration for random(). If I remove werror, it does generate the warning, but it compiles (as expected) but more interestingly, it works perfectly fine. It generates a number as expected. What am I doing wrong? Does C89 support random or not? What am I supposed to include that’ll make the warning go away? The man page mentions nothing other than stdlib.h which is included.

A viable alternative as mentioned by the manpage, would be arc4random(), however I am pretty sure it doesn't exist cross-platform.

My test snippet is

#include <stdio.h>
#include <stdlib.h>

int main()
{
int test;
srandom(5);

    test = random() % 190;
    printf("Hello World %d\n", test);
    
    return 0;

}

And it generates the following output:

main.c:15:5: warning: implicit declaration of function ‘srandom’; did you mean ‘srand’? [-Wimplicit-function-declaration]
   15 |     srandom(5);
      |     ^~~~~~~
      |     srand
main.c:17:12: warning: implicit declaration of function ‘random’; did you mean ‘rand’? [-Wimplicit-function-declaration]
   17 |     test = random() % 190;
      |            ^~~~~~
      |            rand
Hello World 115
2

There are 2 best solutions below

2
P.P On BEST ANSWER

Both random and srandom are not part of the C standard. They are POSIX functions, so compiling with -std=c89 doesn't make their prototypes available when you compile.

You can define one of the following at the top of your source file to make their prototypes available:

#define _DEFAULT_SOURCE

or

#define _XOPEN_SOURCE 600

This enables POSIX as well as other extensions. Check out feature test macros for details on these macros.

10
Lundin On

Does C89 support random or not?

It does not.

Now, since I am compiling with -std=c89, -pedantic, wall and werror, it refuses to function correctly due to having a warning about an implicit declaration for random().

That's because when you enter strictly conforming mode, the compiler will not allow the incredibly stupid practice of placing non-standard functions inside standard libraries. As described in the accepted answer of Is a compiler allowed to add functions to standard headers? a conforming implementation is not allowed to spew out identifiers that may collide with the application ("affect the behavior of a strictly conforming program").

The root of the problem is POSIX, which is a broken standard not harmonised with ISO 9899.