mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

But std::allocator is also forward-declared in MyClass.h, so you don't need to include <memory> in the header.

daviddoria commented: Thanks for the help! +4
mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

"MyClass_details.h" is not a "real" header because it is only included by the cxx files of the derived classes. You can change the extension to .cxx if it makes you happier but it makes no difference. As long as MyClass_details.h is not included in any other libraries, you are not breaking the rules.

@AD: stop talking about putting the myVector class definition in the MyClass.h, that is exactly what david wants to avoid. Of course, doing that solves the compilation error, but it does not solve the problem.

mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

You still have the problem that myDerivedClass is not aware of the struct myVector (at least not its full declaration). I would suggest:

//in MyClass.h

#ifndef myclass_h
#define myclass_h

class MyClass
{
  public:
    MyClass();
    ~MyClass();

  protected:
    struct MyVector;
    MyVector* vecPtr;
};

#endif

//in MyClass_details.h
#include <vector>

struct MyClass::MyVector
{
  std::vector<double> v;
};


//in MyClass.cxx
#include "MyClass.h"

#include "MyClass_details.h"

MyClass::MyClass()
{
  this->vecPtr = new MyVector;
}

MyClass::~MyClass()
{
  delete this->vecPtr;
}

//in MyDerivedClass.h
#ifndef myderivedclass_h
#define myderivedclass_h

#include "MyClass.h"

class MyDerivedClass : MyClass
{
  public:
  void DoSomething();
};

#endif

//in MyDerivedClass.cxx

#include "MyDerivedClass.h"
#include "MyClass_details.h"

void MyDerivedClass::DoSomething()
{
  this->vecPtr->v.push_back(1); //"invalid use of incomplete type 'struct MyVector'
}
mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

I think, you have to make the pointer a private or protected member, because the compiler will say it is incomplete because it should be accessible to an outside part (like main()) which has no idea what the real declaration of myVector is. Since the VecPtr can be dereferenced in the main() function then main() needs to know its type. By making it private or protected you only require that myClass or myClass and all its derived classes know of the complete declaration of myVector, respectively. May I suggest you make the class myVector as nested in myClass (by forward-declaring in either the private or protected part), there will be less chance of name clashes that way.

mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

I would recommend you switch to cmake instead, but to fix your makefile. Add the "$(pkg-config --cflags --libs cairo)" to CPPFLAGS, like this:

CPPFLAGS += $(pkg-config --cflags --libs cairo)

I'm pretty sure that or a variation of it should do the job, but I'm not an expert on makefiles.

mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

Don't use the code from sundip, it is erroneous.

In your original code, there is a memory leak because you loop again and reallocate the memory for a new array on top of the previous one. Since the destructor of all those Fuzzy objects don't get called, the n value keeps on going up and up. So after the first while-loop iteration, that first for-loop with n as bound will corrupt the memory and cause a crash.

Try this code and it works (I tried it, not that I needed to, really..):

#include <iostream>

using namespace std;

class Fuzzy{
    public:
        static int n;
        Fuzzy () { n++; };
        ~Fuzzy () { n--; };
        int position[48];
        int score;
    };

int Fuzzy::n = 0;

int main () {
  Fuzzy* ent;
  for(int iter=0; iter<50; ++iter) {
    ent = new Fuzzy[20];
    for( int n = 0; n < Fuzzy::n; n++){
      for( int i = 0; i < 48; i++ ){
        ent[n].position[i] = 24;
      }
      ent[n].score = 567;
    }
    cout << Fuzzy::n << endl;
    delete[] ent; //delete the array you have.
    cout << Fuzzy::n << endl;
  };
  return 0;
};

The output is 20 0 20 0 20 0 20 0 ... as it should be. If you take out the delete[], it will print 20 20 and it will crash.

mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

You are right, you can use both for either purposes, they are both methods for mutual exclusion of threads. So, I was wrong in saying that the critical section was not applicable, because frankly, I have never used them and I understood them as a way to just lock a piece of code (which is what they were years ago when I was still doing pure win32 applications). Now, on cross-platform coding, I work exclusively with Boost.Thread for all sync functionalities and it does not include critical sections, only mutexes.

Your question and the msdn page on critical sections poked my curiosity about the efficiency of mutexes vs critical sections. It is indeed expected that critical sections are faster because they try to avoid the kernel calls with a spin count. However, looking at the source code of Boost.Thread, I saw that the win32 mutex version is implemented with a spin count to avoid kernel calls just like critical sections. Read this nice article about it. So my recommendation: use the Boost.Thread library, this way you are pretty much guaranteed the best performance, flexibility and platform-independence.

mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

There is no implementation for either of these methods:

void Mob::set_data(string name, int level, int given_xp, int given_gold, int attack, int defence, int max_hp, int max_mp, int max_tp, int attack_spd);
void Mob::add_ability(Ability);
mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

Ok, it needs to be explicit:

pArray[i] = int(imgArray[i]);
mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

The code you posted is a bit weird, what is C1dArray?

Anyhow, simply put:

...
imgArray = new unsigned char *[size];

myStream.read(reinterpret_cast<char *> (imgArray),(fileSize)*sizeof(unsigned char)); //notice fileSize not size
//set the nullterminating char, if you really need it (IMO you don't).
imgArray[size-1] = 0;

int* pArray = new int [size];
for(int i=0; i<size; ++i)
  pArray[i] = imgArray[i];
mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

C: forget it, it is possible of course, but I can comfortably say that people don't really make a conscious choice to program in C. Usually it is because either it is a special very low-level platform for which C is the only choice, or because its an old library that is too large to translate to C++.

C++: well, that would be my choice for sure, and I have just implemented a massively-multi-threaded application with network interfaces in C++. For threads, look at Boost Thread library, it is the defacto standard nowadays, and it is cross-platform. C++ is fast, effective and very flexible, and allows both high-level and low-level programming, but it also has quite a steep learning curve.

Java: well, it's easier to learn and has more built-in capabilities that are cross-platform. But in my opinion, it's not worth suffering the presence of the virtual machine (and all its seductive demons, like garbage collecting) and the pseudo-denial of low-level programming. (but I have a bias opinion on that, as you can probably tell)

mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

I know you solved the problem, but may I suggest a more elegant method IMO. This is a typical case where an interface class and multiple inheritance could do very well:

//Callback.h
class IMouseClickCallback {
  public:
    virtual void MouseClickCallback() = 0;
};

//Client.h
class Client : public some_other_base_if_any, public IMouseClickCallback {
  private:
    ...
  public:
    ...
    virtual void MouseClickCallback(); //with implementation in cpp
    ...
};

//wherever_else.cpp
#include "Callbacks.h" //no need for forward-declarations, just include the header of the interface.

void SetMouseClickCallback(IMouseClickCallback* Obj);
mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

>>But more than that, I've learned that when I go too fast I can get ahead of myself and these sorts of errors pop up.

Great! As additional comment, I would say that the best way to go about a problem like this is to program it incrementally. In your case, it was simple and you were able to get all the functions programmed before compiling once, but then you get some errors that pile up and it becomes harder to find and debug them. Even, on simple problems, it's a good idea to compile many times, at every new function you add, this way you know exactly what causes the error in compilation or in the output of the newly added function. Of course, as you gain experience you can write more code or even complete libraries without compiling once, but let that come by itself, no rush.

@kirennian: >> So would I be right in saying that you only include headers which are required for the classes actual header itself and that those which are required for the .cpp methods, you include at the top of the .cpp file? That makes logical sense I suppose.

Absolutely, the point is that your header is intended to be included by other parts of the software (other source files or headers). So the more things you include in your header, you possibly will increase the size of the code that includes it, requiring more compilation time, and possibly …

kirennian commented: Thanks :) +2
mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

Well, there are several places to put it, depending on what you want. I am not an expert with VC++, so the names I give my not apply directly (they would apply directly to Borland C++Builder and VCL) but usually they correspond well. Usually there are callback functions, like OnClick() for the button click, but for initialization and finalization, such as OnCreate() (at creation of the window / application), OnShow() (at appearance of the window), OnDestroy() or OnRelease() (at destruction of window / application), OnHide() (at the disappearance of the window).

Otherwise, there are also the actual constructor/destructor of the custom Form classes that VC++ would generate (I assume). Or even deeper, you can put it in the WinMain function that you can find somewhere in the project's source file, but I wouldn't recommend that, it's too far deep and could have some nasty consequences.

Hopefully somebody here with more knowledge of VC++ can tell you more exactly where to find these places to put init code.

mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

Well if the names are mismatched, then you could implement your own look-up table. But there are two options to avoid it. First, you can change the name of the function in the DLL to match the command strings. Or second, you can export the functions from the DLL with a different name than their internal name in the DLL's implementation (i.e. an alias). Look at internalname vs. entryname, for example on the msdn page on EXPORTS and the module-definition file.

Of course, if you cannot touch the DLL's implementation, then you have no choice but to implement your own look-up table, as your original solution, and with the __stdcall fix it should work fine.

mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

>>I'd also recommend putting all includes into the header file rather then the .cpp

NO absolutely not, if we are talking about best practices in coding. OP: The way you did it is fine. You include as few headers as you can in your headers and include the headers you need for the implementation in the CPP.

And yes, the error is because of the mismatch of the parameters of the function, and I'm sure of that. And your call to it is also mismatched:

DisplayTemperatures(Temperatures, NumTemperatures, AverageTemp);

You have more problems than that though. Your function ComputeAverageTemp takes a useless parameter (AverageTemp) and when you call it, you need to store the return value in you variable AverageTemp. The same goes for Low and High.

GetTemperatures(Temperatures, NumTemperatures); 
			  Sleep(1500);
			  AverageTemp = ComputeAverageTemp(Temperatures, NumTemperatures); //take the last parameter out of the ComputeAverageTemp function
			  Sleep(1500);
			  int lowTemp = Low (Temperatures, NumTemperatures);
			  Sleep(1500);
			  int highTemp = High(Temperatures, NumTemperatures);
			  Sleep(1500);
			  DisplayTemperatures(Temperatures, NumTemperatures, AverageTemp, lowTemp, highTemp); //update your header prototype for DisplayTemperatures
			  Sleep(3500);
mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

>>For iBinBag do you think, i need to explicitly declare the input array ? or create a new one and delete ?
You mean, do you need to make the input array as dynamically allocated or not? That depends on the implementation, if you know of a certain maximum size, then a static array would do just fine. If you don't know the size of the array and have no expected maximum (which I doubt, because I remember from some course on internet protocols that there is some maximum packet size), then you need to somehow announce the size of the incoming array to iBinBag and allocate it dynamically.

Compilation errors, well try to solve them as much as you can, if you are stuck, post them here.

mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

Well, this line:

DIAG_SelectHardware = (LPFunction1)GetProcAddress(hGetProcIDDLL,"DIAG_SelectHardware");

Already is a look-up in a look-up table of the DLL. It looks in the look-up table of the DLL for the function corresponding to the name "DIAG_SelectHardware", and outputs the function pointer to it. So if all the functions you have are in that DLL, then that's all you need, forget about making a look-up table on top of that.

One remark, you do know that you should not call FreeLibrary until the very end, when there is no more chance that you might be calling any of the DLL functions again.

mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

Well, two things I can say.

First, the error is because you didn't match the calling convention. In the DLL function, the keyword __stdcall sets the calling convention to the standard calling convention (which is needed for DLL exported functions, in most operating systems). But the default calling convention in C++ functions is __cdecl. So that is the error, it says the function DIAG_ReadMem32 is not __cdecl. So, to fix the problem, you have to declare the function pointer type as

typedef int __stdcall (*myfunction)(char *[], char[]);

Second, if all the functions that you need in the look-up table are from a DLL. Then, look at run-time loading of the DLL. This is because the DLL already has a look-up table in it, so you could use it instead of making your own on top of it. In linux, the commands are dlopen(), dlsym(), dlclose() to load a .so, get the function pointer by name (called symbol), and close the .so, respectively. In windows, the corresponding functions are LoadLibrary(), GetProcAddress(), CloseLibrary(). You can look those up by yourself.

mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

With Linked-list, recursion is your best friend:

template<typename T>
node<T>* copyList(node<T>* front){
 if(front)
   return new node<T>(front->value,copyList(front->next));
 else
   return NULL;
};
mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

Thanks for that article, very informative! I didn't know so much about condition variables other than the big performance problem described in that article, by having experienced it but without looking into that problem. In either case, as I said earlier, condition variables are still best suited for a task queue (as in the article), but still, in CPU-bound MMT apps, it would be nightmarish to use them, so I'll keep my fast yielding loop.

for the OP's problem though, condition variables could be used, although I still believe a simple mutex will do because it is not a master/worker-queue implementation but just a master thread and a status checker -thread.

mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

We don't just solve assigments here! You start it, get some code going, and post specific problems with the code you have. We have to see that you have been making a real effort to solve this problem by yourself. We only give help to cross the few hurdles you meet along your way, we don't just drive you all the way.

BTW: don't post such general titles as "C++ program", try to be more specific about it like "Writing a Photo Store Management Program"

mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

NO, if only the return type differs, they cannot be overloaded (i.e. have the same name). C++ standard specifies that overloading is only for different parameters (their types or their number), not return types.

So, to have different return types. You have a few options (in order of what's easier to what's harder to do):
1. Change the name of the function to something else.
2. Pass the return variable by reference as an additional parameter to the function, and then overloading will work.
3. Add a dummy parameter to the function prototype that distinguishes the functions
4. If applicable for the implementation of the function, make it a function template with the return type as argument, and instantiate the template function explicitly.

mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

>>The efficient (and elegant) way to do this is to use a condition_variable.

First, can you explain how condition variables can actually help in the OP's context?

Second, you say efficient? I've tried to use condition variables from Boost for a massively-multi-threaded application I was developing and they were so slow (wake-up intervals are ridiculously long) and inefficient that it made them completely inapplicable for CPU-bound MMT apps. I had to resort to a simpler method with a yielding loop and double-buffered variables as synchros (and mutex lock, of course). So maybe they are applicable to a network-bound or user-bound application because the efficiency requirements are extremely low (given the network or user-event bottleneck) and they are elegant and simple to use, but they are certainly not efficient.

mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

>>does that mean that I need to overload the operator to work with my class?

NO absolutely not. DO NOT OVERLOAD THE -> OPERATOR!

The correct syntax in your case is:
points.x

mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

The only thing you have to make sure is the the second thread is not just constantly checking the state, you have to leave enough time of unlocked mutex for the worker thread. So:

//This would be really bad:
void StatusCheckThreadFunction() {
  Lock mutex
  while(still_running) {
    Check the status of sockets.
    Print the status in listview.
  };
  Unlock mutex
};

//This is what it should be:
void StatusCheckThreadFunction() {
  while(still_running) {
    Lock mutex
    Check the status of sockets.
    Print the status in listview.
    Unlock mutex
    Sleep for, say, 100 ms (leaving the unlocked to allow the working thread to work).
  };
};
mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

Oh, wait, I just remembered, you have to cast to the base class to call the overloaded functions of the base class:

DerivedClass derivedClassObject;

derivedClassObject.computeFunction();

BaseClass& baseClassRef = derivedClassObject;
baseClassRef.computeFunction( 1.0 );
mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

I just verified in my own code, and I use this extensively in my code so I know this works. Are you sure this is what you have:

class BaseClass
{
public:
    void setInputParameter()
    {
        inputParameter_ = inputParameter;
    }
    
    void computeFunction( const double& inputParameter )
    {
        setInputParameter( inputParameter );
        this->computeFunction();
    }
    virtual void computeFunction() =0;
private:
    inputParameter_;
}

class DerivedClass : public BaseClass
{
public:
   void computeFunction()
    {
        fooVariable_ = 20.0;
    } 

private:
    double fooVariable_;
}
mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

>>I can't make the computeFunction in the derived class protected because I have to be able to access it as a public function.

Then make it public in the base class and in the derived class.

In other words, all the overloaded functions (virtuals and non-virtuals) of a name need to be in the same class.

mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

>>saying a function of that form can't be found.
This is because if you have a non-virtual function in the base class and a non-virtual function of the same name in the derived class it will "hide" the one in the base class and the compiler won't find it.

mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

The problem is that you need to have the same access right for the overwritten function in the derived class, otherwise, the compiler will call the public function first. So, simple correction:

class BaseClass
{
public:
    void setInputParameter()
    {
        inputParameter_ = inputParameter;
    }
    
    void computeFunction( const double& inputParameter )
    {
        setInputParameter( inputParameter );
        this->computeFunction();
    }
protected:
    virtual void computeFunction() =0;
private:
    inputParameter_;
}

class DerivedClass : public BaseClass
{
protected: //see here, make this function protected to match the base class.
   void computeFunction()
    {
        fooVariable_ = 20.0;
    } 

private:
    double fooVariable_;
}
mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

Did you consider making a method instead? such as:

template <typename T>
class node
{
public:
	T nodeValue;	//data held by the node
	node<T> *next;	//next node in the list

	//default contructor with no initial value
	node() : next(NULL)
	{}


	//constructor. initialize nodeValue and next
	node(const T& item, node<T> *nextNode = NULL) :
		nodeValue(item), next(nextNode)

	{}
	
        node<T>* clone() {
                if(next)
                        return new node<T>(nodeValue,next->clone());
                else
                        return new node<T>(nodeValue,NULL);
        }; 
};

... in main():
	cout << "Copied List: " << endl;
	newHead = front.clone();
	writeLinkedList(newHead, " ");
	cout << endl << endl;
...
mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

Well from what I see, if you don't need to use the std::stack<int> in the second thread and you are only using the struct array, then you don't need a mutex. For example, you have a redundant variable in the struct, that is, the "index" variable. You could set that index to -1 for sockets that are not used and then your second thread can only traverse the array and check the index, if it is greater or equal to zero you can display whatever you like (fileSize or totalBytes ..). This way the mutex is not necessary.

However, the overhead associated with locking a mutex and as you say the communication between threads is ridiculously small compared to the network bottleneck. So don't worry about that, the network communication is going to be the main bottleneck, no doubt, regardless of how small the files are.

Finally, your strategy seems quite alright to me, so far.

mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

To get rid of the extra line, use this instead:

int iter = (int)floor((stop_temp - start_temp + step / 2.0) / step);
mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

You replaced one problem with the same problem. The main point with my solution was that you cannot do an exact number of iterations with a float because float is not exact, regardless of how you put it. You need to use an integer value to count the iterations, not a float.

If the ceil function gave an error like "cannot convert double to int" then use "int iter = int(ceil(..));" to explicitly cast to int.

mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

First, a critical section is not really the synchro you need for this, you want to use a mutex (may I recommend from Boost Thread).

Second, you say you have a _list_ of structs. Is that a loose terminology or is it an actual std::list. If it is a std::list or another kind of linked-list, then it is marginally ok to read-only without protecting with a mutex. If it is a std::vector or any dynamic array, std::map, or anything like that, then NO it is not OK to read-only without a mutex. The reason for that is if in the middle of your read operation (even if it is very short) the thread scheduling might switch to your main thread and reallocate the memory (say to insert elements) and when you come back to the read operation, the memory addressing will be corrupt and your application will go hay-wire.

So as a pretty general rule, if you share any sort of dynamic memory (anything involving a new/delete) between threads, shield all read-only, write-only, and read-write operations on that memory by locking a mutex before, especially if it is a highly-dynamic memory (e.g. lots of elements added and erased from a list per second). There are cases where that rule is a bit over-the-top and could be relaxed, but you always need to be careful, and the fact that you are posting this thread shows that you are careful, which is good!

Anyways, if you are …

mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

You had some things the wrong way around:

subarray(int* Array, int start,int end)
{
	typedef int* ptr;
	ptr sub;
        int count = end - start; //the sub-array's size is not "end", but "end - start".
        if (count <= 0) //check that you actually have a sub-array to create.
          return; //here, your function has no return type?
	sub = new int[count]; //now allocate "count" size.

	for(int i=start; i<end; i++)
	{
		int j = 0;
		//Array[i]=sub[j]; //this sets Array to sub, do it the other way around:
                sub[j] = Array[i];
		j++;
	}
	for(int l=0; l<count; l++)//added as an after thought
		cout<<sub[l] << ", ";
        delete[] sub; //never forget to delete, don't leave memory leaks.
}
mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

>>If the DEBUG_NOTICE(nr,"Some text") is to be shown in, lets say, a MessageBox, would it be ok to point the whole thing at a string?

Look at the definition of the DEBUG_NOTICE MACRO, it uses "std::cout << Z << endl;", this outputs to the console (DOS command prompt in windows). It's not a string. You could make a macro just the same for any other text output (I personally would not recommend MessageBox, because you will spend all your time clicking on OK to go from one messagebox to the next.. a console or TextBox print would be more suitable (or TMemoBox if you are using VCL)). Anyways for a MessageBox, you can define the MACRO differently:

#define DEBUG_BOX(X,Y) if(X <= DEBUG_VERBOSITY) MessageBox(NULL,(std::string(__FILE__) + ":" + itoa(__LINE__) + " " + Y).c_str(),"Debug notice", MB_OK);

Note: I only know the win32 messagebox call.


>>Are there any real benefits or advantages of using a debug macro against 'assert' - other than you don't have to include a header?

Well first of all, you have to put the debug macro in a header with header guards, otherwise the compiler will say "multiple definitions of the macro" if you use it in multiple source files. Second, an assert is a completely different thing that serves a completely different purpose. An assert is just a way to abruptly stop the execution when an error condition is found. The debug print macro is used to output a whole bunch of …

mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

that simple: floating point values on a computer always approximate the real value to some round-off error (about to the 7th significant digit for float and to the 20th significant digit for double). So the comparison i<=stop_temp is not going to work all the time because even when i is 11, it might actually be 11.0000034 or something like that and thus, not equal to stop_temp (which also will not necessarily be exactly 11 either).

So to fix the problem, use an integer-valued iterator, like this:

int iter = ceil((stop_temp - start_temp) / step); //ceil will get the smallest integer value that is greater than "(stop_temp - start_temp)/step".
  for(i=start_temp; iter>=0 ;iter--,i=i+step)
  {
    C=(5.0/9.0)*(i-32);
    F=32+(9.0/5.0)*i;
    cout<<setprecision(2);
    cout.setf(ios::fixed);
    cout<<setw(10)<<C<<setw(10)<<i<<setw(10)<<F<<endl;

  }

EDIT: ceil is found in <cmath> by the way. (so you need also #include <cmath> at the start)

mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

Ho, well the thing I posted is the classic debug print MACRO.

Line 3-5: This checks if the #define symbol "DEBUG_VERBOSITY" was defined through the compilation command-line arguments (like -DDEBUG_VERBOSITY=4), if not, it will define it as 5. This is the verbosity level of the debug output. This means if the first number in the call DEBUG_NOTICE() is smaller than DEBUG_VERBOSITY, the notice will be outputted otherwise it won't.

So in line 12 and 14, the 2 and 8 are the "importance rank" of the notice. This way you put the more important messages to print with a lower number (like 1 to 4 or something) and lesser important messages that you would only use when you are doing really deep debugging, would have higher numbers. This way, when you compile with low verbosity you get less debug printouts and you can turn debug printouts back on by increasing verbosity. This way you don't have to manually take out the debug printouts once you have a working software, you just leave them there and compile with verbosity 0 for the release version.

Now, line 7 is a MACRO, of course, the first parameter is that "importance rank" for the message, while the second parameter (Y) is what you would put "cout << HERE << endl;" to print the message on the terminal or console. The only other thing there is __FILE__ and __LINE__ which are standard special defines that all compiler provide, __FILE__ is the name of …

mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster
mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

MACROs are evil! Don't use them. From the looks of it, that you need is a look-up table. If you are restricted to C, from the looks of your code that is the case, then you can do this:

struct myKeyword {
  const char name[];
  int ID;
};

myKeyword *keywords = {{"INCLUDE",1},{"INT",2},...};

void IsKeywordOrNot() {
  int j=0;
  flag=0;
  for (j=0;j<18;j++) //search for keyword & # of keywords = 18.
  {
    if (strcmpi(lexeme,keywords[j].name)==0)
    {
      temp.assign(lexeme,keywords[j].ID);
      flag=1;
      break;
    };
  };
};

Another thing that is evil are global variables (like keywords, flag, lexeme), so try to pass them as parameters to the function instead and not make them global variables.

If you are not restricted to C, but can use C++ syntax and STL containers. I would suggest you use std::map instead:

#include <map>
#include <string>

std::map<std::string,int> keywords;
void initKeywords() {
  keywords["INCLUDE"] = 1;
  keywords["INT"] = 2;
  ...
};

void IsKeywordOrNot(int& flag, std::string& lexeme) {
  if(keywords.size() == 0) 
    initKeywords();
  int j=0;
  flag=0;
  std::map<std::string,int>::iterator iter = keywords.find(lexeme);
  if(iter != keywords.end()) {
    temp.assign(lexeme.c_str(),iter->second);
    flag = 1;
  };
};
mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

Here the recursion idea is that you start with a vector of digits v_in to pick from and an empty vector of digits v_out where a combination can be put. Then at this point any one of the digits you have in v_in can be placed in the next slot of v_out to start a new combination. So you can loop for every digit in v_in, add it with v_out to get v_next, copy all the other digits of v_in into v_remain, and recursively call back the same function with v_next -> v_out and v_remain -> v_in. Once there is no more digits in v_in, you should have a full combination, and you just print it out with cout.

mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

No. It's so you can have fun

Well, if you look at our posts, we have been having fun with this.

I think the problem got turned into: What is the most weird, convoluted and elaborate way to simply print "Hello World!" 20 times?

mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

Well, as a start, you need to split the number into each base 10 digit, for example:

std::vector<int> SplitDigits(int Number) {
  std::vector<int> result;
  while(Number > 0) {
    result.push_back(Number % 10);
    Number /= 10;
  };
  return result;
};

That's a start, now you go from there and figure out how to construct each possible combination (hint: use recursion, think of how a factorial is calculated).

mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

so, if I understand correctly, if I put in gdb break-points around the code, I can make it run to a certain point, and I will then have access to all variables within the scope? would be very nice.

Oh yeah, that's the whole point of gdb. What other way were you using it? And there are a lot of IDEs which integrate gdb in the user interface (like KDevelop), while others have their own debugging environment (like VC++). Otherwise, you have to deal with gdb with the command-line, which is actually a bit hard to use.

mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

Wow... that's a lot of questions. That's why I said "you are stepping into the realm of const-correctness", it is not a simple issue because as you said it is a way to restrict the code in a language that is built on a philosophy of freeing the code. And you exemplify very well what I was saying about "beginners" (and don't take offense, if I say so) that are not too warm to the idea of const-correctness. I will try to give some answers to your many questions:


>>I'm not seeing any more computational power coming out of it--is that correct?

Not entirely correct. There can be a speed up, but it is usually not significant in the whole scheme of things. The reason is, for the computer to use a variable, operate on it, and write it value, it has to take those step, i.e. take the variable value from the memory, do some operation with it on the CPU, and write the new value back to the memory. By a const qualifier, the compiler can omit the last operation. This is a very rough approximation of the process, and usually the processor will not do it whether the variable is const or not. But the more you tell the compiler, the better it can optimize in general. But still, I wouldn't think that the performance gain, if any, would be really measurable (I may be wrong).


>>it just make the …

mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

Oh, you mis-wrote the conversion operator, it should be:

class vec3f
{
        private:
        GLfloat q[3];
	public:
	GLfloat& x() { return q[0]; };
        GLfloat& y() { return q[1]; };
        GLfloat& z() { return q[2]; };
        

	vec3f(){};

	vec3f( GLfloat x, GLfloat y, GLfloat z )
	{
		q[0] = x;
		q[1] = y;
		q[2] = z;
	}

	operator GLfloat *()
	{
		return q;
	}
}

That has to work, it is too simple to not work.

mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

The problem is that pTSL1_Commands->TSL1_ReadMemory32 is a "method" not a "function". The difference is that a method has the implicit "this" pointer to the object passed to it, while a function only has the parameters of its prototype declaration.

So a function pointer, if you need to use one and not a function object, can only point to either a global or namespaced function, or a static member function. In either case, you cannot get the implicit "this" pointer passed, so you will have to make it an explicit parameter if you need it.

So in your case, if you have data inside TSL1_Commands and need that object in the code of your commands, then add a pointer to a TSL1_Commands object as the first parameter of your function pointer prototype, and make all the command functions "static". That should work, but, of course, it's a bit annoying and function objects would do much more nicely.

mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

Well you are stepping into the realm of const-correctness which is this idea that if you want to be rigorous, you should put const everywhere where a variable is constant or required to be constant. You are right that a lot of people (especially beginners) are frustrated at the const qualifier because it causes annoying errors when part of the code is const-correct and part of it is not. The basic problem is that const-correctness has a spreading effect (which is very desirable). If you make your library completely and rigorously const-correct, it sort of forces people that use your library to be const-correct, at least to a certain level.

But why?
Well experienced programmers like to know what a function does without having to look at the code in it (only at the interface or function prototypes). const qualifiers are a way to announce to outside programmers not to worry that a particular object or function-parameter may change, especially when it is not obvious. The C++ language is strongly typed and thus spreads this qualifier around to sort of enforce the law. This means:

class Time {
  private:
    int hour;
    int minute;
  public:
    int getHour() const; //const means that reading the value of hour does not change any data in the Time object.
    int getMinute() const; //same here, the caller is aware that this function does not modify the Time object.
    int getNonConstHour(); //say you omit const.
};

ostream& operator <<(ostream& out, const Time& value) { …