srand48() : Unable to compile due to scope issues on Windows in Dev-C++.

Dev-C++ version 5.5.2 (Windows 7) gives compilation error that occurs in the last line in main():

[Error] 'srand48' was not declared in this scope


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <sys/time.h>
#include <cmath>
#include <cstdlib>
#include <stdlib.h>

extern double drand48();
extern long lrand48(/*long*/);
extern int rand();
extern void srand(long seedval);



//main program
main()
{

//set random number generator
struct timeval tp;
struct timezone tzp;
gettimeofday(&tp,&tzp);
srand48(tp.tv_usec); //compilation error occurs here: [Error] 'srand48' was 
                     //not declared in this scope
}
Last edited on
> extern void srand(long seedval);
There is no 48 here.


But your modification gives error: s.cpp:(.text+0x23): undefined reference to `srand(long)'
I'd suggest you delete these lines.
1
2
3
4
extern double drand48();
extern long lrand48(/*long*/);
extern int rand();
extern void srand(long seedval);


There's a whole load of rand related prototypes already in stdlib.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
       #include <stdlib.h>

       double drand48(void);

       double erand48(unsigned short xsubi[3]);

       long int lrand48(void);

       long int nrand48(unsigned short xsubi[3]);

       long int mrand48(void);

       long int jrand48(unsigned short xsubi[3]);

       void srand48(long int seedval);

       unsigned short *seed48(unsigned short seed16v[3]);

       void lcong48(unsigned short param[7]);

       int rand(void);

       int rand_r(unsigned int *seedp);

       void srand(unsigned int seed);

Thanks for the suggestion. but the original issue still remains.
Are these your own functions or existing functions that you just are just trying to use?
I have copied program on Simulated Annealing from a book Alan Parker, Algorithms and Data Structures in C++, in last section of chapter 3.
Well, srand48 is not a standard C++ function. It seems to be some kind of POSIX function. Not sure it's available on Windows.
Yeah, they're common extensions, if your 'common' isn't windows (I guess).

The very next lines in the manual page.
1
2
3
4
5
6
   Feature Test Macro Requirements for glibc (see feature_test_macros(7)):

       All functions shown above: _SVID_SOURCE || _XOPEN_SOURCE
///
CONFORMING TO
       POSIX.1-2001, POSIX.1-2008, SVr4.


I suppose you could fake things with
1
2
3
4
5
6
7
8
9
long lrand48() {
    return rand();
}
double drand48() {
    return rand() / (double)RAND_MAX;
}
void srand48(long seedval) {
    rand(seedval);
}


The '48' versions would typically have much longer cycle times than the standard rand functions.

But if you really want to improve things, then use this instead.
http://www.cplusplus.com/reference/random/


Thanks, a lot for your detailed response. I would try your trick soon. However, I ran on Cygwin & got it running using g++. So, it is possibly a Unix vs Windows environment issue.

However, the code was problem area reported in a bigger code on Simulated Annealing, which is from book by Alan Parker, Algorithms and Data Structures in C++, in last section of chapter 3.

I am still facing the Segmentation fault on running g++ there, with the command: $ g++ -Wall -Wextra -Werror -c sp3.cpp -o sp3.o; followed by ./sp2.

The full code is at: https://onlinegdb.com/HyruMTmdN. It reported the same error at onlinegdb too, but in absence of any details provided, cannot understand what is causing the error.

If the link is not accessible, please tell; then will try some other option - although I feel attaching file is not an option here. Tried putting the code here, but was rejected due to length more than the max. allowable.
Last edited on
Yes, something funny with one of the loops.
1
2
3
4
5
6
7
8
9
10
11
12
13
$ g++ -Wall -Wextra -g bar.cpp
bar.cpp: In function ‘void create_operation_array()’:
bar.cpp:86:49: warning: operation on ‘i’ may be undefined [-Wsequence-point]
     for(j=0;j<NO_SQUARES;i++) op[i++] = PLUS+i%2;
                                                 ^
bar.cpp: At global scope:
bar.cpp:319:6: warning: ISO C++ forbids declaration of ‘main’ with no type [-Wreturn-type]
 main()
      ^
bar.cpp: In function ‘int main()’:
bar.cpp:323:23: warning: unused variable ‘random_neighbor_cost’ [-Wunused-variable]
     int optimal_cost, random_neighbor_cost;
                       ^

Well, two funnies actually.
1. The for loop starts off with j, but ends up incrementing i.
Such a loop will never exit.

2. You should really write the statement as
1
2
3
4
 {
    op[i] = PLUS+i%2;
    i++;
}


And also make main return an int explicitly.
Thanks a lot for telling the errors in logic. But, the program is taking infinite time to run, both in onlinegdb, & in cygwin. The book even states that the program may not be able to find soln. The new code with only the warnings removed is at: https://onlinegdb.com/SJ0dzGSd4. Would soon implement your suggestions.

It ended after around 30 mins. in cygwin, & am giving the last line of outputs:
Calculated cost 1
data[present_op[i]]<<data[present_op[i]]<<data[present_op[i]]<<data[present_op[i]]<<data[present_op[i]]<<data[present_op[i]]<<data[present_op[i]]<<data[present_op[i]]<<data[present_op[i]]<<data[present_op[i]]<<data[present_op[i]]<<++**++*+++

It seems all is wrong, but would see why cost is 1 only.

Last edited on
I'm not surprised it takes so long with all that debug code you've thrown in.

And you didn't fix ALL the problems I pointed out, so what next?

default: cout<<data[present_op[i]]; break;
I changed this to output the value, rather than just printing a silly string.


$ time ./a.out | tail -3
in print_result 
Calculated cost 1
11111111111++**++*+*+

real	0m0.568s
user	0m0.664s
sys	0m0.152s
$ time ./a.out | tail -3
in print_result 
Calculated cost 1
11111111111*++*+*+**+

real	0m0.493s
user	0m0.576s
sys	0m0.140s
$ time ./a.out | tail -3
in print_result 
Calculated cost 1
11111111111*++*++++*+

real	0m0.550s
user	0m0.604s
sys	0m0.184s
Thanks, but as never ran a such long running program; so the overhead incurred by printf() was not known. Now, it runs un-believably faster in comparison.

In fact, am unable to understand the workings of the program properly. But that is another issue.

Would request you to quantitatively compare by some way the overhead incurred by printf() (in this program, as earlier) without making a call to them, as it takes a lot of time then.
Last edited on
Sorry, for the last query as could not understand the significance of 'time' used for timing. I timed the commented version (named sp_c.cpp) by the set of commands: $ g++ sp_c.cpp -o sp_c, time ./sp_c | tail -3. And it took ten times (i.e., 3-4 sec.) the time as compared to the time reported by you for the un-commented version.

But, there is still something to ask for.
If try the commented version (named sp_c.cpp) as at : https://onlinegdb.com/Bkeuc5H_V, by the set of commands (on cygwin) : $ g++ sp_c.cpp -o sp_c, ./sp_c; then it took around 30 mins. to complete.
While the un-commented version (named sp_nc.cpp) still completed in under a second by the commands: $ g++ sp_nc.cpp -o sp_nc, ./sp_nc.

I am curious if the delay in the commented version is a function of printf (that caused to have only a 10 times difference), or a function of display. By display, I mean the screen display of the printf took so much addtl. time. If so, then the display is another factor, & hence causes a very high order of difference in time taken, i.e. around 20 mins. vs 3-4 seconds, as for program timed for printf.
Last edited on
I am unable to find the significance of (lrand48() >> 4) in the statement at line #54 : build_list->side = (lrand48() >> 4)%(SQUARE_SIZE_LIMIT)+1; for the code in function: void get_list_start(square_list ** list), in file at https://onlinegdb.com/S1DQiAH_E

Any pointer in that direction would help me a lot.
Last edited on
> By display, I mean the screen display of the printf took so much addtl. time.
Exactly.
For every line output, it has to scroll the 50-100 lines visible on screen, and maybe 1000's of lines in the history buffer (what scrollback buffer did you set).

1
2
$ ./a.out | wc -l
18053368

Considering that your instrumented code outputs over 18 MILLION lines of text, that's a hell of a lot of scrolling!.
You might want to consider targeting your logging at specific areas of interest. You're not going to wade through that volume of output and discover meaning.

Using "| tail -3" is very efficient, since tail only keeps an internal ring buffer of the 10 most recent lines. It only outputs when it's input is complete (the pipe is closed).

> as compared to the time reported by you for the un-commented version.
Not all machines are equal.
Cygwin is a compatibility layer between the OS your program expects (Linux) and the OS you really have (Windows). What needs to be done to maintain that illusion varies depending on what you're doing, but the cost is never zero.

Besides, my machine will take seconds to run the program if I try to do any work with the 200MB of data the program spews out.

It's only meaningful to get performance data on the version without voluminous printfs, when optimisation is enabled.
1
2
$ g++ -O2 sp_nc.cpp -o sp_nc
$ ./sp_nc


> I am unable to find the significance of (lrand48() >> 4) in the statement at line #54
https://en.wikipedia.org/wiki/Linear_congruential_generator
Such generators are notoriously bad random number generators in the least significant bits. Some examples of rand()%2 will produce nothing but 0,1,0,1,0,1,0,1,0,1,0 ....

So >>4 will throw away the bottom 4 bits, presumably with the hope that the resulting pseudo random number is a bit more random and a bit less pseudo.
Very sorry, but had bad experience in getting no response earlier. So, placed elsewhere in parallel, the initial problem.
I got some good response, that continued me there.

Also, I am first time here; so deserve excuse for this error; as knew nothing about the responsiveness here.
Last edited on
Topic archived. No new replies allowed.