Banfa 597 Posting Pro Featured Poster

In a strict sense the compiler compiles a translation unit it into an object form - and may not (doesn't have a right to) change any observable logic.

Ignoring the specific case in question this statement is wrong as a generalisation.

For instance the compiler is required to change the constant 0 when used in a pointer context into the platforms representation of the NULL pointer, which note is not required to be all bits 0.

The compiler is specificly required to change the observable logic in just the way you have claimed it has no right to.

Banfa 597 Posting Pro Featured Poster

That is not quite true, when the notify method is called it gets a Subject pointer to some object. You know that object can definitely not be a Subject because Subject is abstract and so can not be instantiated.

You have been passed a base class (Subject) pointer to a derived class (possibly an Alarm).

You can use the typeid operator or dynamic casting to determine the type of the object being pointed to. Obviously you will not be able to call any derived class functions through a base class pointer so some conversion may be required.

Banfa 597 Posting Pro Featured Poster

Firstly if cpu utilisation is only getting to 70% there is nothing to worry about. All programs are getting all the cpu time they require with time (30% of the available time) left over.

A single run of your program however only opens a single file and reads it, if you are talking about multiple files then you must be running the program multiple times. It is the operating systems responsibility to share processor time between process that need it even if some of those processes are demanding 100% of the cpu time the operating system will on the whole not them them have it.

If you are still worried then are are things you can do but they will slow down the operation of the program.

You could run the program at a lower priority. The priority is an attribute that the operating system uses when scheduling tasks, lower priority programs get less processor time. You can change the priority either programatically by making approriate function calls or by using a utility like nice (try "man nice") to run the program with a reduced priority.

You could interrupt the read loop in the program with a yield or a small sleep.

However I would recomend that you do neither of these until you get to the point where you computer is getting problems because it is running out of processing resource which is isn't currently, it still has 30% of that resource left.

Banfa 597 Posting Pro Featured Poster

You mean to say that return 0 means, by default, success (irrespective of platform). Hurray!
So, does all this means return EXIT_SUCCESS is redundant?

May be a little but good programming practices dictate that you use symbols with good semantic means rather than magic numbers.

My guess is that before standardisation EXIT_SUCCESS didn't exist and it was common to return 0 for success. At some point EXIT_SUCCESS was introduced to meet best practices of not using magic numbers but returning 0 had to be maintained as a success return for backwards compatibility.

People just continue to use 0 rather than EXIT_SUCCESS because it is rather easier to type.

Banfa 597 Posting Pro Featured Poster

Just to clarify it is explicitly stated in the C standard that main if returns a value of 0 (or EXIT_SUCCESS) then the program will return a value to the system that indicates the program was successful.

Note that is not necessarily 0; if the system in question does not treat 0 as success then it is the compilers or the exit codes responsibility to interpret the 0 value returned from main and return the correct value to the system.

If you return 0 from main and the system thinks your program is returning an error then you are using a non-conforming compiler and should think about changing it.

Ancient Dragon commented: Sounds logical to me :) +27
Banfa 597 Posting Pro Featured Poster

However, with my compiler at least, if you uncomment line 5 ("unsigned multiplyerType"), this thing will balloon from 1-byte to 12!

I can explain that if you haven't already.

You changed the basic type of the bit field when you uncommented line 5. It went from trying to put bits into a 1 byte field to trying to put bits into a 4 byte field so it started again at the beginning of a new field. Since the new field is 4 bytes long (an unsigned) it needs to be on a 4 byte boundary so 6 padding bits are put into the original field followed by 3 padding bytes. The first 2 bit field is taking 4 bytes of space!

Then you change back to a 1 byte field so the compiler starts again, again. It puts in 31 padding bits into the 4 byte field and starts a 1 byte field for the final three bit fields.

The it adds 5 padding bits to complete the field. At this point 9 bytes have been used (1 byte field, 3 padding bytes, 4 byte field and 1 byte field), however this is a structure and needs to conform to normal structure padding rules. The structure contains a 4 byte field so needs to align on a 4 byte boundary. To ensure that this happens in a array the compile adds 3 more padding bytes for a total of 12 bytes.

And the moral of this …

Fbody commented: This looks like a better wording of what I had theorized. Thanks. +1
Banfa 597 Posting Pro Featured Poster

I get this error from your code using gcc

BitFlags.h:12: error: ISO C++ prohibits anonymous structs

What compiler are you using, this is improtant of course because bitfield behaviour is very much platform dependent.

Anyway after naming the struct I get a size of 4 for the struct as you have it defined.

if you want the bitfield size to be 16 bits you need to declare it unsigned short or if you want to use negative values short .

I ended up with this

union bitFlags {
	unsigned short flagGroup; //provide a 16-bit backbone (on 32-bit systems)
	struct { //the bit field
		signed short multiplierRule : 2; //multiples-of-a-kind rule,
		//"on" causes values to be 2x,3x,4x three-of-a-kind value resp.
		unsigned short straightRule : 1; //"on" activates bonus for a straight in a single roll
		unsigned short threePairRule : 1; //"on" activates bonus for three pairs in a single roll
		unsigned short hardWinRule : 1; //"on" activates the hard win rule-set
	} s; //close the bit field structure
}; //close the union

P.S. I would have thought you should know that "it wont compile" is a bit useless without the actual compiler errors :p

Banfa 597 Posting Pro Featured Poster

Actually no you haven't "its not working" is not a proper description of its actual behaviour. All that tells me is that it doesn't do what you want it to do. That doesn't tell me what it actually does.

Banfa 597 Posting Pro Featured Poster

Is this nearly bulletproof?

I think so probably.

I have to admit that I have a, possibly irrational, prejudice against atoi. I do not like the way you can tell how many characters it has parsed without parsing them yourself, as you code does. Every digit gets parsed once by atoi and once by your own loop to verify that it is a digit. That inefficiency, although minute, just sticks in my craw and makes me want to do something different. I do use atoi but normally only in simple little tools that are not destined for consumer contact.

I may be a bit prejudiced against atoi but wild horses could not force me to use strtok. It contains static buffers (well pointers I suspect) so is not re-entrant or thread-safe.

If I was writing this routine then I would either cut out the call to atoi and the while loop and put in a call to strtol or I would cut out the call to atoi and and expand the while loop to do the calculation of the value as well.

while (*p != '\n' && *p != 0 && i < 3 )
    {
        if (isdigit(*p))
        {
            char *end;
            date[i++] = strtol(p, &end, 10);
            if (isSeparator(*end)) p = end + 1;
              else              break;  // non-date character
        }
        else  break;                    // non-date character
    }
while (*p != '\n' && *p != 0 && i < 3 )
    {
        if (isdigit(*p))
        {
            date[i] = 0; …
Banfa 597 Posting Pro Featured Poster

1. The constructor is for exactly what you have stated "initialize variables or assign dynamic memory". In this case there is no dynamic memory so it is for initialisation of member variables. If you don't implement the constructor then between constructing the object and calling read() your object will contain garbage. You use the constructor to initialise the member variables to some zero state.

2. "const Polynomial10& pol" - that is a constant reference to a Polynomial10 object. References have some similarities with pointers (what you learnt pointers yet?). Some differences are

  • A reference must be initialised so you can not have a NULL reference like you can have a NULL pointer. It also makes it quite a lot harder (but not impossible) to have an invalid reference where as producing an invalid pointer is quite easy. They are considered to be safer than pointers.

  • Once assigned a reference can not be change to reference a different object. All operations on a reference are operations on the object it references.
  • References use the member access operator . not the pointer to member access operator ->

The const is important to, it means that the function called is guaranteeing not to change the object that being reference.

gnarlyskim commented: very informative and helpful +1
Banfa 597 Posting Pro Featured Poster

Always keeping as much precision as possible is definately not a bad option, however there are others.

For instance there is no point in keeping 15 decimal places of precision if the value represents a real world item with a fixed quantum of precision, for example cash. I can have £6.349999 because cash is not available in that quantum, I must have either £6.34 or £6.35.

The problem is I see cash as having decimal places and force that perception onto the computer where it does not need it. Instead of holding the value in pounds I can hold it in pence, 635p as an integer. Now the physical limit on the quantum change of the value is matched by the computers limit on the quantum change of the variable, 1 in both cases.

Back to the original problem. You are holding a percentage as an integer and want it rounded off to 1 decimal place. Everyone is saying use a float and perform werid calculations to try to round it that are bound to not work quite correctly at some point due to the non-exact nature of floats.

Why not hold it in an integer in units of 1/10 of 1%?

I am not saying this is the right way. That is dependent on your program. What I am saying is if you really want to limit the number of decimal places you are using this is the way to do it. However if …

Banfa 597 Posting Pro Featured Poster

Almost everywhere you have a loop and access your arrays you have an out of bounds array access, for line declared as

bool line[78];

then if it is accessed as line[N] N must conform to the constraint 0 <= N < 78

However

void firstline(bool firstline[])
{
	int y;
        for(y = 0; y <= 78; y++)
        {
                if(y != 38)
                firstline[y] = 0;

y can be 78 - out of bounds

void coutline(bool coutline[])
{
	int z;
        for(z = 0; z <= 78; z++)
        {
                if(coutline[z] == 0)

z can be 78 - out of bounds

void rules (bool rules[])
//Put line in and follow 8 rules
// Rule: 1   2   3   4   5   6   7   8
//      111 110 101 100 011 010 001 000
//       0   0   1   1   1   1   0   0
{
	int x;
	bool nextLine[78];
	for (x=1; x < 78; x++)
	{
		//rule 1
		if (rules[x-1] == 1 && rules[x] == 1 && rules[x+1] == 1)
			nextLine[x] = 0;

x+1 can be 78 - out of bounds

Also it is bad practice to litter your code with the magic value 78 when in call cases that value has the same semantic meaning, width of the pattern being created. declare a const int at the top of the file with a good semantic name and use that, then if the width of your pattern changes you only have to change 1 place.

Banfa 597 Posting Pro Featured Poster

Not for template functions (and classes).

A template function are the instructions to the compiler on how to write the function given the parameter types... the template of the function.

When the compiler compiles your code and sees a call to a template function it looks up the template function and uses it to create an actual function that it compiles into the object for the file.

However the compiler works on a single file at a time. If the template function is not defined somewhere in the file being compiled the compiler can not create a real function from the template when it sees the function call because it can not see the template.

So the definition of the template function needs to be visible to the compiler when it is compiling your file there are 2 ways of doing this

  1. Put the definitions of the template functions in the header.

  2. Put the definitions of the template functions in a different file, NOTE not a cpp file because best practice is not to include cpp files, and then include that file into the header.

Whatever you do at the time the compiler sees the template function call it must have already seen the definition of the template.

hkBattousai commented: Thank you for the explanation. +4
Banfa 597 Posting Pro Featured Poster

I can't explain why it is working at home, but that is the nature of undefined behaviour, however at line 48 of your code listing you free the array just before you start writing values into it.

mitrmkar commented: ... the nature of undefined behaviour +5