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
CodePudding user response:
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.
CodePudding user response:
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.