Register a SA Forums Account here!
JOINING THE SA FORUMS WILL REMOVE THIS BIG AD, THE ANNOYING UNDERLINED ADS, AND STUPID INTERSTITIAL ADS!!!

You can: log in, read the tech support FAQ, or request your lost password. This dumb message (and those ads) will appear on every screen until you register! Get rid of this crap by registering your own SA Forums Account and joining roughly 150,000 Goons, for the one-time price of $9.95! We charge money because it costs us money per month for bills, and since we don't believe in showing ads to our users, we try to make the money back through forum registrations.
 
  • Post
  • Reply
shodanjr_gr
Nov 20, 2007
So I've had this question regarding const-qualifying a function. Basically I have a class that contains a mutex
and a function Lock(scoped_ptr<CTraits>). that allows a client to grab the mutex. The function takes as an argument a scoped pointer, in which it returns a traits object that will automatically release the mutex when it falls out of scope.

My question regards whether the Lock() function should be qualified as const or not. What if I have separate LockForRead and LockForWrite functions that provide access to an underlying ReadWriteLock instead?

Adbot
ADBOT LOVES YOU

raminasi
Jan 25, 2005

a last drink with no ice
I guess my real question was "What on earth is an 'invalid' pointer if it's not just a non-dereferencable one." What an oddly narrow guarantee.

shrughes
Oct 11, 2008

(call/cc call/cc)

shodanjr_gr posted:

My question regards whether the Lock() function should be qualified as const or not. What if I have separate LockForRead and LockForWrite functions that provide access to an underlying ReadWriteLock instead?

Make neither const. Locking a class moves it from an "unlocked" state to a "locked" state. This kills the constness.

Or make both const, since locking for write and releasing it doesn't actually modify the object in any significantly different way from locking for read and releasing it.

Jabor
Jul 16, 2010

#1 Loser at SpaceChem

GrumpyDoctor posted:

I guess my real question was "What on earth is an 'invalid' pointer if it's not just a non-dereferencable one." What an oddly narrow guarantee.

Hardware can be weird. A "valid" pointer is one that won't crash your program just by existing.

As an example, some hardware platforms have separate registers for pointers and data - a platform like that could check that any pointers have sane values when they get loaded into a pointer register, and raise a processor exception if they don't. The spec guarantees that producing a pointer to one-past-the-end of an array won't cause such a trap - but makes no such guarantees about pointers further away then that.

As a less esoteric example, it's guaranteed that a pointer one-past-the-end of an array won't have overflowed around to something close to zero.

Flobbster
Feb 17, 2005

"Cadet Kirk, after the way you cheated on the Kobayashi Maru test I oughta punch you in tha face!"
To relate it to a similar concept, think about C++ iterators -- the semantics of end() are just like the semantics of p + N for a buffer of length N. The iterator end() is valid, clearly, since the method exists and returns an object, but dereferencing it would result in undefined behavior.

shodanjr_gr
Nov 20, 2007

shrughes posted:

Make neither const. Locking a class moves it from an "unlocked" state to a "locked" state. This kills the constness.

Or make both const, since locking for write and releasing it doesn't actually modify the object in any significantly different way from locking for read and releasing it.

Well those are the two options that I've been torn over however I was wondering if there is a concensus/convention on this.

shrughes
Oct 11, 2008

(call/cc call/cc)

shodanjr_gr posted:

Well those are the two options that I've been torn over however I was wondering if there is a concensus/convention on this.

My preferred style of API is to have the lock acquisition object itself be the thing which has the API for making modifications. So instead of having

code:
{
    scoped_ptr<LockHolder> holder;
    thing->LockWrite(holder)
    thing->MakeModification(x);
}
and instead of having

code:
{
    WriteLockHolder holder(thing);
    thing->MakeModification(x);
}
I prefer this:

code:
{
    WriteLockHolder holder(thing);
    holder->MakeModifications(x);
}
"Holder" isn't really the term I'd use, that's just forum posting stupidity on my part.

In such a case, naturally a WriteLockHolder would have to take a non-const thing as its argument.

Whether a ReadLockHolder would take a const thing or not is situational. If it helps you out with a real problem with const correctness that would prevent mistakes from being made, go for it.

rjmccall
Sep 7, 2007

no worries friend
Fun Shoe

GrumpyDoctor posted:

I guess my real question was "What on earth is an 'invalid' pointer if it's not just a non-dereferencable one." What an oddly narrow guarantee.

There's no concept of a "valid" pointer in the standard(s). There is a concept of undefined behavior. It is undefined behavior to perform pointer arithmetic that would give a result pointing outside the object containing the base pointer, except to point immediately after it. It is also undefined behavior to dereference a pointer that does not point at an object, except that assignments into valid storage are magic.

This is a ridiculously useful property for optimization, because without it you have to assume that any array access of unknown index might touch any object whose address has escaped.

Max Facetime
Apr 18, 2009

Well there is the Core Language Issue 523:

quote:

523. Can a one-past-the-end pointer be invalidated by deleting an adjacent object?

Section: 3.7.4.2 [basic.stc.dynamic.deallocation] Status: open Submitter: comp.std.c++ Date: 8 July 2005

When an object is deleted, 3.7.4.2 [basic.stc.dynamic.deallocation] says that the deallocation “[renders] invalid all pointers referring to any part of the deallocated storage.” According to 3.9.2 [basic.compound] paragraph 3, a pointer whose address is one past the end of an array is considered to point to an unrelated object that happens to reside at that address. Does this need to be clarified to specify that the one-past-the-end pointer of an array is not invalidated by deleting the following object?

So the behavior is maybe "under-specified"?

Princess Kakorin
Nov 4, 2010

A real Japanese Princess
I've run into a #include issue, I'm not sure how to fix it.
I keep getting the 'Multiple definition of ..." error when I place my header file 'draw.h' inside of 'gameCore.h', stating that I already have it included inside of 'main.cpp'. Except it's not included in main.cpp.

But when I throw 'draw.h' inside of 'gameCore.cpp', everything works fine, but then I can't include 'draw.h' in any other files or the 'Multiple Definition of ...' error pops back up.

I'm not sure how to go about fixing this, and yes I am using header guards.

TasteMyHouse
Dec 21, 2006
Do you have any non-inline, non-template functions defined in draw.h? Because that would cause you to have a function defined in more than one compilation unit which would confuse the linker.

Princess Kakorin
Nov 4, 2010

A real Japanese Princess
I'd never heard of an inline function until now, just did some reading up on them.
Yeah, I have 2 non-inline functions defined in draw.h.

So, if I'm understanding everything correctly, I just need to make them inline functions, or stick them into a template?

nielsm
Jun 1, 2009



Princess Kakorin posted:

I'd never heard of an inline function until now, just did some reading up on them.
Yeah, I have 2 non-inline functions defined in draw.h.

So, if I'm understanding everything correctly, I just need to make them inline functions, or stick them into a template?

Yes either that, or move them to a separate compilation unit.

TasteMyHouse
Dec 21, 2006
nielsm's suggestion is most likely the one you should be taking. Unless there's some particular reason for you to be defining the function as inline, you should be PROTOTYPING it in the header file, then DEFINING it in exactly 1 seperate .cpp file.

If you define functions in a header and use "inline" to get rid of the linker errors that would otherwise occur, what you've done here is make every compilation unit that includes that header will then have the definition of that function as a dependency.

lets say you have project named "qux" with three cpp files (foo.cpp, bar.cpp, and baz.cpp) which all include 1 header file (header.h). When you compile for the first time, the preprocesser will textually insert the contents of header.h into each of the .cpp files, giving you three separate compilation units. these compilation units will then be compiled to object files -- lets call them foo.o, bar.o, and baz.o. then, the linker links all three .o files together to get your file executable, "qux".

If header.h contains an function (int bap(int p1 ,int p2)) definition that isn't declared inline , when it comes to the linking stage, the linker will see that this function exists in all 3 compilation units and won't know which one to pick -- there needs to be exactly one definition of each function for the linker to properly resolve all references to a particular function. If you mark it inline, then compiler treats it specially -- it can actually sub the body of the function in at every location that it is called, or, if it judges this is a bad idea, it can tell the linker that even though it's defined in more than one unit, they're all the same anyway and the linker can just go ahead and throw away all but one copy.

The problem with this is that what if you want to make some kind of change to the implementation of bap? something that doesn't change the parameters or return value, but maybe optimizes the way the function works a little bit?

If you have the function defined in the header, then to alter the definition you have to alter the header. then, your build system (make, or visual studio, or whatever) will be forced to regenerate foo.o, bar.o, and baz.o -- even though functionally, nothing changed about them.

What is much better is to either create a new cpp file, or to move the definition of bap into one of the existing .cpp files -- say, foo.cpp. Now, if you need to alter bap in a way that doesn't change the function's interface, the other object files using the interface will not need to be regenerated.

Doing this right will give you much faster builds.

nielsm
Jun 1, 2009



Using inline also risks you defining two different functions with the same name and not noticing.

If foo.cpp includes abc.h and bar.cpp includes def.h, and both abc.h and def.h define a function void florb(int), but the two definitions are different, different things will happen depending on whether florb() is marked inline: If it's not, the linker will complain as it should. If it is marked inline, the linker will pick one of the two different implementations and use that, resulting in one of foo.cpp or bar.cpp calling the wrong florb().
Inline functions carry that risk.

Colonel Taint
Mar 14, 2004


I had a similar problem when I recently got into C++.

Basically, external linkage is your friend.

Qualify the prototypes in your header with extern, and put the definitions in a cpp file.

like so:
code:
//foobar.h
#ifnded FOOBAR_H_
#define FOOBAR_H_

extern void foo();
extern void bar();

#endif

//-----------------------
//foobar.cpp
#include "foobar.h"

void foo() { bar(); }
void bar() { foo(); }
That's pretty much the practical end of what's already been said.

Edit: er.. just realized I may have been confusing this with a similar but different problem. It won't hurt anything to have the extern keyword there, but it turns out the keyword is not needed for function declarations.

Colonel Taint fucked around with this message at 01:18 on Nov 24, 2011

Dijkstracula
Mar 18, 2003

You can't spell 'vector field' without me, Professor!

Thinking about this problem in terms of external linkage really doesn't make any sense here, as you're within a single compilation module. Getting into the habit of blithly using extern when you don't actually want identifiers shared between modules could get you into trouble when you start working on larger programs.

Colonel Taint
Mar 14, 2004


I assume you mean because of the increased probability of naming collisions? If it's anything more than a small C++ project, it's probably a good idea to consider using namespaces.

In any case it seems more reasonable to me to move the functions to a separate compilation unit than making the functions inline for the purpose of avoiding multiple definitions.

BizarroAzrael
Apr 6, 2006

"That must weigh heavily on your soul. Let me purge it for you."
Hi thread! I was working in C# in my last job, my first programming role in the games industry after doing a bunch of games testing. I got made redundant at the beginning of the year and am finding there are plenty of roles I would otherwise go for that require C++ skills, and annoyingly, a role I had a phone interview for and was told wanted me in for an in-person interview, ended calling back after a month of silence to tell me they wanted C++ now. The problem may also be how I learned C#, on the job researching the solutions to problems as I came to them, which resulted I think in holes in my knowledge or just not knowing terminology. I keep booking up on C# itself, but I think going back to basics on OOP might be good for me.

So I'm looking to get a recognised C++ qualification of some kind. I can't magic up loads of professional experience but I think it would help me a lot to show I know it. I've found a bunch of 10-12 week evening classes of a couple of hours a week, though obviously I want to find work an move out of my parent's place, so would rather not be tied down. I know that I might be able to get a discount for being unemployed though. I think ideally I want to do a course that takes up the whole day for a few days, or something I can do online that I can get feedback for and some certificate/grade/qualification at the end. Can anyone suggest anything? I live in the UK if it matters, Chichester specifically, but can travel elsewhere to study short-term if needed. I have a bunch of family in London I might be able to stay with.

Or do you think such a plan is pointless, and I should just read the sites and books in the OP and self-teach?

shrughes
Oct 11, 2008

(call/cc call/cc)
I don't get what is up with people's idea that to learn some CS thing, they should take a course. Especially when that thing is a programming language!

I know that my general attitude to somebody who took a course in C++ after college because he wanted to learn the language would be, How did that course make you not suck at programming? I certainly won't think that such-and-such person is going to be non-craptastic at C++ after a mere 10-12 weeks.

You'd be much better off in my mind and the mind of any company worth working for if you taught it yourself and wrote some frakking code in C++. If they're unsure of your ability (and they will be, no matter what is on your resume, even if you won the Nobel prize in C++) they'll have you do some kind of test, i.e. make such-and-such application in C++, or do this problem on the whiteboard, or whatever. To get a job you'll need to not suck at C++, hopefully. To get interviewed, the best thing to do is to have evidence of having used C++ in some non-trivial non-retarded way on your resume. When they see "B.A. took a course in C++" they'll (hopefully) think you're some shmuck who sucks at programming so bad he signed up for a course in a programming language and then bragged about it on his resume. When they see "B.A. wrote some ______ thing in C++" they'll (if they're not HR drones or something) think you're an actual programmer who can write actual code.

Of course you're in the UK and from what I can tell employers there might possibly be insane, so YMMV, wait and see what tef or Fib or qntm have to say.

pseudopresence
Mar 3, 2005

I want to get online...
I need a computer!
My impression is that certifications are mostly good for jobs at companies large enough and incompetent enough that the person evaluating your CV doesn't actually understand what the job will involve. If I did have a certification in C++, I wouldn't list it on my CV, because it signals the wrong thing; wanting to appear to know C++, rather than actually knowing C++.
There are many good books about C++, many good blog posts, etc. You can teach yourself. If you want a more well-rounded education in software engineering and computer science, check out some of the free material on http://www.cl.cam.ac.uk/teaching/1112/ or http://ocw.mit.edu/. And yeah, write some frakking C++.

P.S. Don't do games, flee games, games is a terrible industry.

shrughes
Oct 11, 2008

(call/cc call/cc)
I remember when I applied for a job at some small game company after graduating college. They wanted to pay hourly and they wanted to pay $19 per hour.

Hahaha no.

roomforthetuna
Mar 22, 2005

I don't need to know anything about virii! My CUSTOM PROGRAM keeps me protected! It's not like they'll try to come in through the Internet or something!

shrughes posted:

I remember when I applied for a job at some small game company after graduating college. They wanted to pay hourly and they wanted to pay $19 per hour.

Hahaha no.
That's better than entry-level with one of the big evil companies, where they'll pay a salary that looks like the equivalent of about $25 an hour, but then demand you work 80 hour weeks with no overtime pay.

That Turkey Story
Mar 30, 2003

shrughes posted:

I remember when I applied for a job at some small game company after graduating college. They wanted to pay hourly and they wanted to pay $19 per hour.

Hahaha no.

Same story for me but for less than that, at a THQ studio, and I foolishly took the job.

roomforthetuna posted:

That's better than entry-level with one of the big evil companies, where they'll pay a salary that looks like the equivalent of about $25 an hour, but then demand you work 80 hour weeks with no overtime pay.

The joke at this particular studio (which is no longer a part of THQ) was that some of the salaried employees made less than those who were payed hourly because pretty much every week was at least a 60-70 hours.

Basically the game industry is mostly poo poo.

HipsLikeCinderella
Nov 8, 2006

It appears that arrays and array accesses don't work how I think they work in C. I have a text file with each line in it containing a string of 32 ones and zeros. What I'm trying to do is load them in an array to operate on them later.

Seems I can read them to my storage array, print out the value immediately after reading it in, and everything seems fine. But when I make the same call to access the array only a couple lines down, something goes terribly wrong. I've been banging my head against the wall trying to figure it out but that doesn't seem to be helping much. Any sort of nudge in the right direction would be immensely helpful.

Here's the problem code, if anything more specific like the input file is needed I can provide one.

http://pastebin.com/8c4LsZHY

The1ManMoshPit
Apr 17, 2005

HipsLikeCinderella posted:

It appears that arrays and array accesses don't work how I think they work in C. I have a text file with each line in it containing a string of 32 ones and zeros. What I'm trying to do is load them in an array to operate on them later.

Seems I can read them to my storage array, print out the value immediately after reading it in, and everything seems fine. But when I make the same call to access the array only a couple lines down, something goes terribly wrong. I've been banging my head against the wall trying to figure it out but that doesn't seem to be helping much. Any sort of nudge in the right direction would be immensely helpful.

Here's the problem code, if anything more specific like the input file is needed I can provide one.

http://pastebin.com/8c4LsZHY

You're only incrementing i by 1 in the loop, even though you are reading more than 1 byte every iteration, so you are stomping over old data with every read.

Also, why is program defined as a 2d array if you aren't using it like one?

HipsLikeCinderella
Nov 8, 2006

The1ManMoshPit posted:

You're only incrementing i by 1 in the loop, even though you are reading more than 1 byte every iteration, so you are stomping over old data with every read.

Also, why is program defined as a 2d array if you aren't using it like one?

Thanks, that helped a lot. I was using a 2d array for some functionality I haven't implemented yet, but seems when I take away the second pair of brackets the program won't compile. Good thing I'll be using them anyway?

HipsLikeCinderella
Nov 8, 2006

One final question while we're on the topic:

Now that I have all the ones and zeros stored contiguously in an array (in char format), I'm trying to operate on substrings using the strncpy function but it's not working. I don't know much about C/C++ IDEs so I'm just using tcc to compile and when it gets to the strncpy line, it just stops there. If I comment it out everything works but obviously that's not an option. Here's the code (and pastebin):

code:
        // reads in instructions starting at 0x00000000		
	for (i = 0; i < 8192; i+=32) {
		line = fgets(&program[i][0], 34, fptr);
		if (strlen(line) < 10) {
			fprintf(ofptr, "Data section starts here. (%d lines)\n", i/32);	  // delete later
			textCount = i;
			break;
		}			
		else {	
			fprintf(ofptr, "%d:\t%s", i/32, program[i]);
		}
	}	
	
	// reads in data segment starting at 0x00002000
	for (i = 8192; i < 1048576; i+=32) {
		line = fgets(&program[i][0], 34, fptr);
		if (line == NULL) {
			fprintf(ofptr, "\nEOF found after %d lines\n", i/32);   // delete later
			dataCount = i;
			break;
		}
		else {	
			fprintf(ofptr, "%d:\t%s", i/32, program[i]);
		}
	}
	
	fprintf(ofptr, "textCount:\t%d\n", textCount);
	fprintf(ofptr, "dataCount:\t%d\n", dataCount);
	
	
	for (i = 0; i < textCount; i+=32) {
		strncpy(tok, program[i], 32);        // this line right here 
		fprintf(ofptr, "Testing at line %d:\t%s\n", i/32, tok);
	}		
	printf("\n");
I guess I'm just too used to Java where if something small is off the compilier usually gives me a heads up. With C I feel like I'm groping around in the dark when I know it's something very trivial I've hosed up. Anyway if I can't figure it out after this problem it's probably time for me to scale back the difficulty.

Good Will Punting
Aug 30, 2009

And as the curtain falls
Just know you did it all except lift weights
Hello again, friends. I was given a Binary Search Tree class example from my professor, and despite my best attempts to understand it fully (even with contacting him, it's an all online class), I'm not getting it. Here's part of the class, and a few lines from the example program that I can't wrap my head around.

code:
template <class T> 
class BinarySearchTree {

   protected: struct Node;
   public:
      BinarySearchTree() { root = 0;} 
      void Insert(const T &a) { Insert(a, root); }

   private:
      void Insert(const T &a, Node * &p);

   protected: struct Node {
      T key; 
      Node *left, *right;
      Node() { left = right = 0;}
      Node(const T &a) { key = a; left = right = 0;}
   };

Node *root; 
};

template <class T> void BinarySearchTree<T>:: Insert(const T &x, Node * &nodePtr) {
Node *newnodePtr; 

   if (nodePtr == 0) {
      newnodePtr = new Node(x);
      nodePtr = newnodePtr; } 
   else if (x < nodePtr->key)
      Insert(x, nodePtr->left); 
   else if (x > nodePtr->key)
      Insert(x, nodePtr->right); 
   }
}
Here is what I'm having an issue with:

code:
int_bst.Insert(10); 
int_bst.Insert(40); 
int_bst.Insert(50);
Every time I step through it on paper and try to type up a question, it opens up another question and I'm getting even more lost. Is root ever being modified? Does 10 become the "root node" upon execution of that first Insert call, that is, the node that the "root" pointer is pointing to? If "root" is never modified, won't it always be == 0 and that first line in the if statement within the function always execute as true?

I have a feeling there's something here that I'm completely missing but I've spent quite some time trying to understand it and when I think I've gotten it, something else changes my view. Thanks in advance. I really have nowhere to turn, and it's not like I can just look at other BST examples because our exams are always problems based off this code.

delta534
Sep 2, 2011
HipsLikeCinderella if you are running gcc on the command line it should spit out an error if there is some sort of syntax error. Otherwise I need more info on what tok is defined as to diagnose the error.

Good Will Punting, Yes, the root is being modified because the insert function takes the pointer by reference not by value. You can learn more about the differences between pass by reference and value here http://www.cplusplus.com/doc/tutorial/functions2/.

Good Will Punting
Aug 30, 2009

And as the curtain falls
Just know you did it all except lift weights
Yeah, I figured it was something like that and I know about ref/value but was confused by the fact that "root" doesn't appear to be passed into the private function via the public by reference.

Upon execution of the third "Insert", does root then point to that lastly inserted value (50 in my example)?

HipsLikeCinderella
Nov 8, 2006

delta534 posted:

HipsLikeCinderella if you are running gcc on the command line it should spit out an error if there is some sort of syntax error. Otherwise I need more info on what tok is defined as to diagnose the error.

Sorry, tok is a char pointer, i.e., the declaration is "char* tok"

It is null before the strncpy call. Let me know if you need any other info, I can post the entirety of the source code (it's not very long) if you need it.

delta534
Sep 2, 2011

Good Will Punting posted:

Yeah, I figured it was something like that and I know about ref/value but was confused by the fact that "root" doesn't appear to be passed into the private function via the public by reference.
In C++ the determination of when something is passed in by reference is done purely by the definition of the function.

Good Will Punting posted:

Upon execution of the third "Insert", does root then point to that lastly inserted value (50 in my example)?

No the insert function follows the tree to the first empty node and inserts there. So it would only change on the first insert.

HipsLikeCinderella posted:

Sorry, tok is a char pointer, i.e., the declaration is "char* tok"

It is null before the strncpy call. Let me know if you need any other info, I can post the entirety of the source code (it's not very long) if you need it.

Tok should be allocated before use. Strncpy does not allocate the space for you.

Good Will Punting
Aug 30, 2009

And as the curtain falls
Just know you did it all except lift weights

delta534 posted:

No the insert function follows the tree to the first empty node and inserts there. So it would only change on the first insert.

Is "nodePtr = newnodePtr;" not the line that modifies root on this first insert? Won't this line have to execute upon every call to insert due to the recursive nature of the function?

Maybe I just have a poor understanding of how recursion works in this case but I'm still pretty lost. :(

roomforthetuna
Mar 22, 2005

I don't need to know anything about virii! My CUSTOM PROGRAM keeps me protected! It's not like they'll try to come in through the Internet or something!

Good Will Punting posted:

Is "nodePtr = newnodePtr;" not the line that modifies root on this first insert? Won't this line have to execute upon every call to insert due to the recursive nature of the function?

Maybe I just have a poor understanding of how recursion works in this case but I'm still pretty lost. :(
You are correct that the line will execute at the end of the recursion, but when it executes, the nodePtr passed to the function won't be a reference to root except the first time it is called. Each recursion has a different nodePtr, being a reference to the branch of tree.

Good Will Punting
Aug 30, 2009

And as the curtain falls
Just know you did it all except lift weights

roomforthetuna posted:

You are correct that the line will execute at the end of the recursion, but when it executes, the nodePtr passed to the function won't be a reference to root except the first time it is called. Each recursion has a different nodePtr, being a reference to the branch of tree.

Ohhh, so when this nodePtr is modified, it isn't a reference to root anymore, it actually has nothing to do with root, it's an entirely separate pointer passed in. Got it. That took entirely way too long for me to understand.

Once again, thanks for the help! I'd be lost without you folks.

InAndOutBrennan
Dec 11, 2008
Can anyone recommend a CSV-parser function/library that has no problem chewing through gigabyte size files without loading the whole thing into memory?

I'm tinkering around with my own but it seems to me that this problem should be solved by now.

Thanks.

Lanithro
Aug 31, 2006
I'm a complete beginner to C, so I've attempted to start writing a command-line dice roller.

My question is with regard to number randomness. What I've written seems random enough, but I'm not sure if it's a "proper" way to go about this. There's a plethora of info regarding this problem, but none of it is particularly concise for a beginner or explains how to properly use it.

Below is my code, and then the results of how many times a number appeared based on D20 rolls.

code:
#include <stdio.h>
#include <time.h>

int x;

int main( int argc, char *argv[] ) {

        if (argv[1]) {
                x = atoi(argv[1]);
        } else {
                printf("You must state what dice you're using (4,6,10,12,20,100).\n");
                exit(1);
        }

        struct timespec tp;

        clock_gettime(CLOCK_REALTIME, &tp);

        srand(tp.tv_nsec);

        printf("D-%d Roll: %d\n", x, 1 + (rand() % x));
}
Dice Roll Value : Number of times it appeared

01 : 154
02 : 135
03 : 138
04 : 171
05 : 162
06 : 128
07 : 145
08 : 140
09 : 152
10 : 142
11 : 123
12 : 152
13 : 151
14 : 120
15 : 159
16 : 139
17 : 146
18 : 135
19 : 150
20 : 136

shrughes
Oct 11, 2008

(call/cc call/cc)
That's fairly reasonable, in that you seeded the rng with the number of nanoseconds, with the goal of avoiding reseeding the RNG the next time you run the program with the same value.

Your choice to use rand() % x is good enough for small values of x for recreational purposes. If you wanted to be anal you should take into account that RAND_MAX + 1 is probably not a multiple of x. (This requires calling rand() more than once, on occasion.)

The idea of seeding a random number generator and using it exactly once is indeed kind of wonky, part of me says you should read some bytes off of /dev/urandom (if on a UNIX system) instead. But relax.

Adbot
ADBOT LOVES YOU

pr0metheus
Dec 5, 2010
What are the usual reasons for why program would change its behavior based on whether or not I cout a float point value or not? That is the results of my computation seem to depend on that, and its confusing me why printing out one of my variables makes any difference.

  • 1
  • 2
  • 3
  • 4
  • 5
  • Post
  • Reply