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

Yes, that would seem like a bug, or at least, very bad static analysis on the part of MSVC. I use mostly GCC or Clang, and I have never seen warnings for such code (i.e., if-else with no return afterwards, which is quite common). I'm quite surprised that MSVC (from VS2010) so incompetently produces such a bogus warning (and that's coming from someone who already has a very low opinion of MSVC compilers).

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

Technically, you could just overload the operators for the classes std::ofstream and std::ifstream. Whenever the stream object is of a class derived from the file-stream classes, then it should pick that overload instead of the non-file-stream overloads, just because the file-stream classes are more derived (specialized) than the non-file-stream classes. So, you could just do this:

friend std::ostream& operator<<(std::ostream& os, const CBase& obj)
{
    os << obj.iMyInt << " " <<
          obj.fMyFloat <<  " " <<
          obj.dMyDouble <<  " " <<
          obj.cMyChar;
    return os;
}

friend std::ofstream& operator<<(std::ofstream& os, const CBase& obj)
{
    os.write((const char *)&obj.iMyInt, sizeof(obj.iMyInt));
    os.write((const char *)&obj.fMyFloat, sizeof(obj.fMyFloat));
    os.write((const char *)&obj.dMyDouble, sizeof(obj.dMyDouble));
    os.write((const char *)&obj.cMyChar, sizeof(obj.cMyChar));
    return os;
}

friend std::istream& operator>>(std::istream& is, CBase& obj)
{
    is >> obj.iMyInt >> 
          obj.fMyFloat >> 
          obj.dMyDouble >> 
          obj.cMyChar;
    return is;
}

friend std::ifstream& operator>>(std::ifstream& is, CBase& obj)
{
    is.read((char *)&obj.iMyInt, sizeof(obj.iMyInt));
    is.read((char *)&obj.fMyFloat, sizeof(obj.fMyFloat));
    is.read((char *)&obj.dMyDouble, sizeof(obj.dMyDouble));
    is.read((char *)&obj.cMyChar, sizeof(obj.cMyChar));
    return is;
}

The problem with this scheme, however, is that it won't work if, at some point, the file-stream objects get casted to non-file-stream class references. This could be problematic if you compose more complicated use-scenarios.

To solve that problem, you could use a dynamic_cast within the operators:

friend std::ostream& operator<<(std::ostream& os, const CBase& obj)
{
    std::ofstream* p_ofs = dynamic_cast<std::ofstream*>(&os);
    if( p_ofs == NULL ) {
        os << obj.iMyInt << " " <<
              obj.fMyFloat <<  " " <<
              obj.dMyDouble <<  " " <<
              obj.cMyChar;
    } else {
        p_ofs->write((const char *)&obj.iMyInt, sizeof(obj.iMyInt));
        p_ofs->write((const char *)&obj.fMyFloat, sizeof(obj.fMyFloat));
        p_ofs->write((const …
mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

precompiled headers are NOT microsoftism they are part of C++

That's half-true. Precompiled headers are certainly not part of standard C++, in the sense of what the ISO standard document describes (which is admitedly also the case for most practical compilation mechanisms). However, it is a common feature that many C++ compilers provide. And in that sense, the feature itself is not a microsoftism. But then again, the way that MSVC implements precompiled headers (using the stdafx.h header) is unique to MSVC and is certainly not portable (and is quite impractical and annoying). Other compilers implement this feature differently, and in much less intrusive manner (just a command-line option to switch it on for all headers). And some compilers don't implement it at all.

If you want to use pre-compiled headers in a cross-platform, portable library or application, then you will have to rely on a cross-platform build system, such as cmake, to handle the specific method different compilers use.

And yes, unless you have a large project, there is no point in using pre-compiled headers, but when you do have a large project, they can be very beneficial to speed up compilation.

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

I found out the way C++ passes arrays around (via a pointer) makes finding the end of the array impossible!

That's true, but you can keep track of how large the array is. That's the usual method.

So my question is how do developers make these string classes?

Typically, an implementation of the standard string class would have three data members:

class string {
  private:
    char* ptr;
    std::size_t size;
    std::size_t capacity;
  public:
    // ...
};

The pointer points to the start of the array of characters. The size keeps track of how many valid characters there are in the string. And the capacity keeps tracks of how many characters the array can hold (i.e., size of the array). Whenever you make an addition to the string and the capacity is insufficient to accomodate the new string, it would just allocate another array that is big enough (with some added margin) to hold the new string, copy all the characters to that new location, and delete the old array. Pretty much everything else is straight-forward from there.

Typically, a real string class implementation, such as that which comes with your compiler, will be much more complicated than that, because of performance optimizations and things like that. But the point is, you can implement a string class quite easily with the above data members.

Do they use C++ or some other language, possibly assembly and plug it into C++ by using includes?

For the …

rubberman commented: Good answer Mike. +12
mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

Here is the corrected code:

StrBlob.h:

#ifndef EXERCISE_STR_BLOB_H_
#define EXERCISE_STR_BLOB_H_

#include <vector>
#include <string>
#include <memory>

class StrBlobPtr;

class StrBlob {
  friend class StrBlobPtr;
public:
  typedef std::vector<std::string>::size_type size_type;
  StrBlob();
  StrBlob(std::initializer_list<std::string> il);
  std::size_t size() const { return data->size(); }
  bool empty() const { return data->empty(); }

  // add and remove elements
  void push_back(const std::string &t)
    { data->push_back(t); }
  void pop_back();

  // element access
  std::string& front();
  std::string& back();


  StrBlobPtr begin();
  StrBlobPtr end();

private:
  std::shared_ptr<std::vector<std::string> > data;
  // throw msg if data[i] isn't valid
  void check(std::size_t i, const std::string &msg) const;
};

#endif

StrBlobPtr.h:

#ifndef EXERCISE_STR_BLOB_PTR_H_
#define EXERCISE_STR_BLOB_PTR_H_

#include <vector>
#include <string>
#include <memory>

class StrBlob; // forward declaration

class StrBlobPtr {
public:
  StrBlobPtr(): curr(0) { }
  StrBlobPtr(StrBlob &a, std::size_t sz = 0);
  std::string& deref() const;
  StrBlobPtr& incr();  // prefix version

private:
  std::shared_ptr<std::vector<std::string> >
    check(std::size_t, const std::string&) const;
  std::weak_ptr<std::vector<std::string> > wptr;
  std::size_t curr;
};

#endif

StrBlob.cpp:

#include "StrBlob.h"
#include "StrBlobPtr.h"

StrBlob::StrBlob() : data(std::make_shared<std::vector<std::string> >()) { }

StrBlob::StrBlob(std::initializer_list<std::string> il) :
  data(std::make_shared<std::vector<std::string> >(il)) { }

void StrBlob::check(std::size_t i, const std::string &msg) const
{
  if (i >= data->size())
    throw std::out_of_range(msg);
}

std::string& StrBlob::front()
{
  // if the vector is empty, check will throw
  check(0, "front on empty StrBlob");
  return data->front();
}
std::string& StrBlob::back()
{
  check(0, "back on empty StrBlob");
  return data->back();
}
void StrBlob::pop_back()
{
  check(0, "pop_back on empty StrBlob");
  data->pop_back();
}

StrBlobPtr StrBlob::begin() { 
  return StrBlobPtr(*this); 
}

StrBlobPtr StrBlob::end() { 
  auto ret = StrBlobPtr(*this, data->size());
  return ret; 
}

StrBlobPtr.cpp:

#include "StrBlobPtr.h"
#include "StrBlob.h"

StrBlobPtr::StrBlobPtr(StrBlob &a, std::size_t sz) : …
Vasthor commented: great tips, and cleared up the things that I thought about the book, it seems the write doesn't even compile the code s/he wrote. +2
mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

Writing a file format that is forward and backward compatible is very easy, and there are many formats that are structured like that. I've dealt and created many file formats like that, and from a programming perspective, creating such formats is actually easier than any other kind of formats.

If Microsoft had used a tagged format then they could have maintained backward compatibility.

There is absolutely no doubt in my mind that incompatible formats are always deliberately made to be. There is a clear economic advantage in creating incompatible formats with each new version of the software, it's part of planned obsolescence.

The worse offenders in my field are CAD software, especially Pro/Engineer and SolidWorks. Every version, and every different license (student, individual, company) comes with a mutually incompatible file format, and really terrible options for exporting to other formats. Basically, once a company commits to a particular CAD software, they have to use it forever, and they have to update everyone's software every year or so. This is a huge and well-known racket.

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

The difference between a=b and a=(A)b (or a=A(b)) is that in the former case it says "assign b to a", and in the latter case it says "create a A object with b, and assign it to a". The point is that because the assignment operators of A and its constructors both have the same acceptable signatures, const A& or int, the ambiguity is the same whether you have "assign b to a" or "create A with b".

Is there a way to explicitly call a typecast operator?

Yes and no. Whether you use (A)b, A(b) or static_cast<A>(b), the situation is the same "create A with b", and as such, will be ambiguous. However, operators can be called explicitly, i.e., the operator functions are fundamentally just functions with a special name that allows the compiler to apply the operator syntax (e.g., operator + allows the compiler to apply it to a + b). But, as functions, they remain callable explicitly with the function syntax, so you can do this:

a = b.operator A();

to explicitly call the operator A member function of the B class. This trick applies to all other operators as well and can be useful to remove an ambiguity. This explicit call will say to the compiler that it should first call that function, which returns an A object, and then assign it to a, which is unambiguous.

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

Clearly, the paths that are ambiguous are: B -> A -> const A& -> A; and, B -> double -> int -> A. I know this because if you remove the double conversion operator it solves the problem (in both cases). Or, you can also make the operator explicit (C++11):

class B
{
    int val;
    public:
    B(int i){val=i;}
    operator A(){return A(val);}
    explicit operator double(){return 0.0;}
};

Now, a reasonable person might expect that the B -> A -> const A& -> A should be preferred over the double-int-path because the binding of an A object to a const-reference const A& seems like a much more straight-forward conversion than the double to int conversion. However, these primitive types are considered arithmetic types, and as such, are given an equal status to other implicit conversions. This is just one of those annoying realities (and due to the C legacy of C++) that you have to watch out for. It is generally dangerous to play with implicit conversions because of these kinds of pitfalls. I tend to stay away from implicit conversions in general. At least, be conservative and mark most of your conversion operators / constructors as "explicit", and selectively make implicit conversions. That's my advise.

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

I second rubberman on his suggestion. I use ffmpeg whenever I need to do any kind of video / transcoding work, it's phenomenal. But I would just like to add that technically ffmpeg is deprecated in favor of "avconv" from the Libav project. avconv is technically an almost drop-in replacement for ffmpeg, it is also a command-line tool (although I think there are some basic GUIs for it), and it is more up-to-date. Essentially, the Libav project is a fork of ffmpeg (i.e., avconv is derived from ffmpeg), and has now surpassed ffmpeg, thus leading the ffmpeg people to pretty much just put a notice on their program saying that it's deprecated and people should use avconv instead. But ffmpeg is still a good tool, of course, but just getting out of date.

But more importantly, avconv is available in Windows directly. In fact, Libav is what VLC uses for all its video work, so, if you know VLC, you know how superior it is to anything else out there, well, that's because Libav is superior to anything else out there.

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

"I seen it with my own two eyes."

Well, one has to be precise. It is reassuring to know that his eyes are his own, and that he only has two, and that he sees with his eyes and not some supernatural ability. It's important in this day and age to make it clear if you are neither a Frankenstein-ian monster nor a mutant. I'd say these people are ahead of their time ;)

I get called a pedant and a tw*t (pick your own vowel) when I return corrected reports. Soul destroying. :(

That's a good point. To that I would add that this whole grammar-nazi thing is also starting get on my nerves. I think that good grammar and writing well should be conveyed more in the form of an art than in the form of reprimands. I think that's the difference between those who appreciate good language and those who don't. Those who don't care will only see grammar as an annoying set of rules to which they constantly have to obey to, or else, get reprimanded. Those who do care see grammar as a useful set of rules to make what they write pleasant to read, clear and fluent. That's really the only reason why I like grammar and linguistics, it's because I appreciate the beauty of well-written text, and I'm proud of myself when I'm able to hit just the right notes when writing. Grammar is not sufficient for writing well, …

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

The difference between while and awhile is explained well here. As for "for a while" vs. "for some time", there is not much of a difference, they are pretty much synonymous, and equally vague. In terms of formal vs. familiar, I think that both are OK in any context, but I would tend to prefer "some time" (or avoid "while" to mean "time") in a formal writing context, but I don't think that's a big deal.

ddanbe commented: Thanks for the info +0
mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

Your assign function takes the parameter by value which means that it creates a local copy of the passed variable and changes only that. If you want the changes made in the assign function to be reflected on the variable passed to it, you need to take the parameter by reference. As so:

void assign(Number& );

//....


void assign(Number& input)
{
    int num;
    num = rand() % 10 + 1;
    if(num % 2 == 0)
    {
        input.type = Even;
        input.value.i = num;
    }
    else  if(num % 2 != 0)
    {
        input.type = Odd;
        input.value.d =num;
    }
}

Notice the ampersand & added to the parameter type, this signifies that the parameter is taken by reference (referring to the variable passed to the function).

Also, I'm using srand, but getting the same values everytime it runs.

Your use of srand is commented out of the code. If you comment it back in, it should work:

srand((unsigned int)time(0));

You do it correctly, i.e., calling it only once at the start of the program and seeding it with a often-changing value (e.g., current time).

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

@Mike, what did you think of Contact?

It was a good movie, but nothing more. I have always had mixed feelings about it. I never could stand the sobby ending and all that wishy-washy obnoxious preachy stuff. The movie has its moments and cool concepts, but the preachy stuff is just too forced.

But if you are talking about scientific accuracy, I don't care much when it's a sci-fi movie that isn't really trying to fit with reality. As long as it is a positive / respectful / realistic depiction of scientists and engineers, I'm happy. A good example of that is Star Trek, as per this essay.
But Contact wasn't very positive in its depiction of science or scientists, in fact, quite disrespectful (and clearly written from an outsider's perspective), and that's another problem I have with that movie. The portrayal of the main scientists is extremely unrealistic and stereotypical. I think that was really the worst part of it. It felt like the writers had no clue about this world, nor did they have any interest to find out about it, they just wrote it to fit their pre-conceived notions and the Hollywood stereotypes. I know that Carl Sagan wrote the book it's based on (and I have not read it), so, I would assume that the screenplay + directing is most to blaim for this particular problem.

Come to think of it, I probably didn't like that movie that much after all. …

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

Yeah, Dark City is definitely a great movie, and really underrated, or maybe it just clashes too much with mainstream.

I just saw Gravity yesterday.. yeah, I know, I'm a little late on that. The movie was really good.. very dramatic and very well shot.

But having a Masters in Space Science and Technology kind of spoiled it a bit. It was kind of hard to "suspend disbelief" when there are so many inaccuracies (maybe subtle enough for the uninitiated, but glaring for trained eyes). I understand that if it was made to be entirely accurate, it would either be one and a half hour of completely uneventful work on the Hubble telescope, or the movie would be over in 5 minutes after one shocking scene. So, I get it, reality is bent to serve the story. But still, it's hard to watch when you go "WTF!" every 2 minutes throughout the movie.

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

Are you talking about template specialization, or are you talking about overloading function templates?

rubberman commented: As usual, you give good examples/links! :-) +12
mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

One of my longtime favorite starts to a song is AC/DC's kick-start to "You shook me all night long":

She was a fast machine she kept her motor clean
She was the best damn woman that I ever seen
She had the sightless eyes telling me no lies
Knocking me out with those American thighs

Another nice one is the biblically-inspired first line of Coolio's "Gangsta's Paradise", it just flows so well and starts off the song so perfectly too:

As I walk through the valley of the shadow of death
I take a look at my life and realize there's nothin' left

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

Well, from looking just in this thread, it appears that both diafol and ddanbe have not been featured... they should be.

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

I second the others, I would nominate rubberman for sure.

And also, the "eternally awesome" deceptikon (or is it "eternally confuzzled".. I'm confuzed.. wink wink).

And, here are a few common encounters in the C++ forum for a long time: Labdabeta, Moschops, L7Sqr, .. that's all I can think of for now.

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

@deceptikon: You misunderstood what the OP was referring to. She is referring to a local class, not a nested class. In other words, this is the case in question:

void f() {
  class inside
  {
    public:
      static int x; // Forbidden!
  };
};

And the explanation for why this is not allowed is that static data members require linkage (be visible to the linker), while a local class is, by definition, not visible outside the function, i.e., it has no linkage. It is simply impossible to have a "visible" entity as a member of an "invisible" entity. Also, there would be a bit of an ambiguity with regards to the static data member if it was allowed (assuming the linkage rules were different), because of the life-time of that static data member. Would it be like a local variable, or like a global variable, or like a local static variable? Where would you define the data member? I assume inside the function. But would that mean that that is the point of initialization? What if you define the data member within a if-statement or some other conditional block?

I think that I am glad that this is not permitted because it would be quite difficult to come to a decent solution to all this ambiguity.

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

alexanpasha already mentioned the very huge systems like mainframes and supercomputers where Linux is extremely important, and at the very least, Unix variants (incl. Linux) dominate the scene completely. Especially in the last decade, the industry has been migrating to Linux systems more aggressively as they realized that it is easier and cheaper to adapt a Linux derivative to work on their systems than it would be to keep maintaining / improving the old legacy proprietary systems (usually Unix variants) that they have been using since the 60s.

But I would also mention another large area of application, which are the tiniest things, i.e., embedded systems. These are the small programmable chips that control various things like various systems in cars, home appliances, TVs / DVD players / DVRs / etc., industrial automation systems, robots, etc... Sure, once in a while you see such a device running Windows CE, or, conversely, not having an operating system at all, but the most common solution is to use a stripped-down distribution of Linux as it fits just perfectly for most purposes, with the exception of cases where hard-real-time operation is needed, which is usually done with QNX (also a Unix variant).

I think that this is really the thing that speaks volumes about Linux (and its Unix-like cousins), that it's so versatile that it can be used in such a wide array of applications with what are essentially the same ground-works (either pimped up to run a super-computer, or stripped down to …

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

The one who does not know how to access it will be confused but that really does not mean that we are restricting user to access it accidently.

That's not exactly true. Private or protected data will restrict the user from accessing the data accidently. It is true that in many cases there are hack-ish ways to access private / protected data, but most of these techniques are, by nature, very deliberate. The likelihood that a careless programmer just happens to access / modify the data by accident is generally very low, and that's the point of those access rights, it's to put access to the data (or functions) outside the realm of "normal" uses of the class or objects. That's what "hiding" means, not to be confused with "protecting".

So, is it not like that programmer has prepared logic in detail thinking that unknown user can’t access it?

When we are talking about normal programming, i.e., not in the context where you are trying to implement security measures, the relationship between the library programmer (e.g., writes the class) and the library user (e.g., uses the class) is one of cooperation, not of antigonism. In other words, the library programmer wants to help the user be able to do his work as easily and safely as possible (safely, as in, without unintentional bugs). And in that context, hiding away certain details can help make it easier for the user to know what he can use safely, …

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

MACROs must be upper-case because this is the convention throughout the programming world of C and C++ and related languages. Basically, MACROs have a number of quirky things about them, and are riddled with pitfalls, and therefore, all programmers want to know, just by looking at something, that it is a MACRO, and thus, need to pay special attention when using it. MACROs allow you to do all sorts of crazy stuff (and that's why they are sometimes the only option), but that also means that they make it easy to cause really weird and hard-to-find errors. So, whenever you use a MACRO for something, you have to put up a huge red flag to announce to the world that this is a MACRO, and the convention for doing that is to use the ALL_UPPER_CASE convention.

and not like other names?

MACROs are nothing like other things (functions, variables, classes, etc.) because they are not handled by the compiler but by the pre-processor. MACROs (or simpler #define tokens) are basically markers for the pre-processor that passes over the code and does a kind of "find-and-replace" for all instances where it finds the MACRO name. The problem is that the pre-processor does not consider context, it does not do scope-based name lookups, it ignores namespaces and scopes, i.e., it is a completely brainless find-and-replace tool. This means that the compiler does not care if the MACRO is used in the right place or if the macro name might refer …

cambalinho commented: thanks for all +0
mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

see how i declare the Age property and the macro defined.

Well, there is an error in your MACRO definition, you have an extra semi-colon. It should be:

#define Property(TypeName,PropertyName,getfunction, setfunction) \
  property<TypeName> PropertyName{std::bind(&getfunction, this),std::bind(&setfunction, this, std::placeholders::_1)};

why isn't showed? it's because is a macro?

Yes. Code completion tools do not, in general, expand macros (they can't risk opening that can of worms). So, they won't show stuff that is buried in a macro.

but what you think about it? and the macro?

I think the macro is completely pointless. And you certainly should never use a name like Property for a MACRO. It should something along the lines of CAMBALINHO_LIBRARY_CREATE_PROPERTY instead. Macro names must obey two conventions: (1) all written in UPPER_CASE_LETTERS, and (2) be prefixed with a unique name that identifies your library. I cannot condone any macro use that does not obey these rules. And the name Property is pretty much the worst possible name for a macro that I could imagine.

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

Sorry about that placeholder _1, it is in the namespace std::placeholders. So, it should be std::placeholders::_1 instead of just _1. The error was due to me being more used to using the Boost version of bind. You can see this docs on bind.

cambalinho commented: thanks for all +0
mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

Well, that variable is there all the time, whether you "need" it or not. So, you might as well use it.

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

I think that function should just be this:

friend istream& operator>>(istream &input, property &dt)
{
    input >> dt.PropertyValue;
    if (dt.setf!=nullptr)
        dt.setf(dt.PropertyValue);
    return input;
}
mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

It's a typo, you had this:

property(std::function<void(void)> GetFunction=nullptr,std::function<T(void)> SetFunction=nullptr)

It should be this:

property(std::function<T(void)> GetFunction=nullptr,std::function<void(T)> SetFunction=nullptr)

Notice the first parameter should be std::function<T(void)>, not std::function<void(void)>, and similarly for the second one.

And the bind expression for the setter should be:

test() : Name(), 
         Age(std::bind(&test::getage, this),
             std::bind(&test::setage, this, _1))
{
cambalinho commented: thanks for all +2
mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

The default constructor is ambiguous with this constructor:

property(std::function<void(void)> GetFunction=NULL,std::function<T(void)> SetFunction=NULL)

because both can be called without any parameters. You should just remove the default constructor because that constructor with default parameters achieves the same result (setting both functions to null) when called without parameters.

The property<int> Age(&getage,&setage); line gives an error because both getage and setage are member functions, not free functions. You need to create pointers to member functions for that. Like this:

test() : Name(), Age(std::bind(&test::getage, this), std::bind(&test::setage, this))
{
    //nothing
}

property<string> Name;
property<int> Age;

That's that.

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

i was wondering if you could give sample code here which uses two files(both a.cpp and b.cpp) in a progarm.

The code I posted in my earlier post is one such example. In the tutorial that I linked to, there is another such simple example.

Like AD said, all projects of any substantial size will have a ton of source files. For example:

  • Boost libraries: ~9,000 .cpp files; ~11,000 headers.
  • My own library: ~400 .cpp files; ~500 headers.
  • GSL (GNU Scientific Library): ~1,500 .c files; ~600 headers.
  • LAPACK: ~3,300 .c files; ~3,500 .f files (fortran); ~800 headers.

and I could go on and on like this.

The main reasons for splitting things into multiple files like this are that (1) files are easier to manage (smaller), (2) a team of developper can work on separate files, and (3) you only have to compile the source files that you have changed. The last point is especially important when projects become large and their development occurs over a long period with many updates and changes. For example, my own library can take up to an hour or two to compile in its entirety, I certainly don't want to have to do this every time I change something somewhere.

i don't know how a program can use two files(up to now ,i haven't seen such a topic in the book).

To compile a project with multiple source files, you just add all the cpp files to your project, …

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

Oh, sorry about those errors, I wrote the thing a bit too quickly. The first error you got about "could not deduce template argument for 'FuncPtrType'" is solved exactly as you did.

The second error, about "expects 1 arguments - 2 provided", has to do with a name conflict. The problem is that the GetProcAddress function could refer to either the member function of CDLLLoader or the Win32 API function of the same name. So, just change the name of that function in the CDLLLoader class:

class DLLLoader {
  private:
    HMODULE h_inst;
  public:

    //...

    template <typename FuncPtrType>
    FuncPtrType GetFunctionPtr(const char* procName) const {
      return (FuncPtrType)(GetProcAddress(h_inst, procName));
    };
};

And then call it with:

CreateFoo = spDLL->GetFunctionPtr<fpFunct1>("CreateFooClassInstance");

That should work (sorry, I can't test it, I'm not under Windows at the moment).

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

Given your example code, here is how it should normally be structured:

In "functions.h":

#ifndef MY_LIB_FUNCTIONS_H
#define MY_LIB_FUNCTIONS_H

int factorial(int n);

bool IsEven(int n);

double sqr(int n);

#endif // MY_LIB_FUNCTIONS_H

In "functions.cpp":

#include "functions.h"

int factorial(int n)
{
    if(n==0)
        return 1;
    else
        return n*factorial(n-1);
}

bool IsEven(int n)
{
    if (n%2==0)
        return true;
    else
        return false;
}

double sqr(int n)
{
    return n*n;
}

And in the "main.cpp":

 #include <iostream>
 #include "functions.h"

 int main() {

     std::cout << "Please enter a number: ";
     int x = 0;
     std::cin >> x;

     std::cout << "You entered: " << x << std::endl;

     std::cout << "Factorial is: " << factorial(x) << std::endl;
     std::cout << "Square power is: " << sqr(x) << std::endl;
     if( IsEven(x) )
         std::cout << "It is an even number." << std::endl;
     else
         std::cout << "It is an odd number." << std::endl;

     return 0;
 };

The way you compile this program is simply that you compile all the cpp files together. You can do this in your CodeBlocks settings or project management somewhere, i.e., you "add sources to project", and it will compile and link together all the cpp files.

compiler generate functions.o . so how to generate functions.obj.

.o and .obj files are the same, it's just a different convention depending on the compilers (and the internal format is different too). Conceptually, they are the same thing. Microsoft's compiler and a few other Windows-only compilers use .obj format, but the vast majority of …

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

There is absolutely no difference between the two. Personally, I prefer int* var because it keeps the variable name clean and the type definition together. But this is merely a matter of personal preference, i.e., it's esthetics. But functionally, it makes no difference at all.

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

I just wanted to point this out. There is a very important error in the truth table that you posted, it should be this:

A B C D Y
0 0 0 0 0
0 0 0 1 0
0 0 1 0 0
0 0 1 1 0
0 1 0 0 1
0 1 0 1 1
0 1 1 0 1
0 1 1 1 1
1 0 0 0 0
1 0 0 1 0
1 0 1 0 0
1 0 1 1 0
1 1 0 0 1
1 1 0 1 1  <--- notice this line (compared to original)
1 1 1 0 1
1 1 1 1 1

Without that correction, there is no way that this could work. And with the correction, it becomes pretty obvious that only A and B matter, so, concentrate on that.

rubberman commented: Good catch Mike - did't look that far! :-) +12
mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

17 people called Sky TV about SkyDrive
x time required to say "Sorry sir/mam, SkyDrive is run by Microsoft, please call them."
<= 5 minutes of lost employee time for Sky TV

Why this would make it to court == a complete mystery.

I wonder if any of these people also asked if they could only access their cloud storage on cloudy days or if it still worked on a sunny day.

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

A long time favorite of mine is "nincompoop". I just think it is such an odd word, by sound and purpose. I don't know if anyone ever uses it. I like odd words, like "vichyssoise" which I use from time to time in formal writing too (in the figurative sense, not to describe a kind of soup).

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

Well, I always sound pretentious anyways, so I'll keep using "one". ;)

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

Whom seems to be disappearing from common usage over here (UK).

I don't understand.. Who seems to be disappearing? I'm asking you, who is disappearing? ... just kidding.

English lost almost all its inflecions except for some sporadic words like "Who / Whom ..." or "while / whilst", and things like that. It really doesn't make sense to keep only a few archaic inflections. They should just be gone, all gone. Are people supposed to learn about grammatical functional cases just so that they can understand these few inflections and disregard it everywhere else where the inflections have disappeared? Seems like a waste and an irritant.

I hate English verb tenses because they tend to reuse the same word a lot.

Really?!? Try learning French, and then, tell me if you still hate English verbs for being too much the same all the time. French has different transformations (inflections) of the verbs for pretty much every single combination of persons, tenses (present, past, future), moods (indicative, conditional, subjunctive, imperative, participle, infinitive), and voices (active, passive, pronominal), plus a ton of irregular verbs (just a few hundred!). So, don't complain about English conjugations being "too simple". The mandatory 13 years of French grammar in school was no joke... more like torture. Part of the reason I like English grammar is that it's so simple, like child-play, easy to grasp and easy to play with and appreciate.

Reverend Jim commented: ;-P +0
mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

What do you guys think?

I think there must be a misunderstanding somewhere. Your boss' idea of what your job responsibilities and skills are, and your idea of that are definitely not the same. Maybe, as far as he knows, he hired an "IT guy", and if his idea of IT is limited to using Outlook, then maybe he thinks it's part of your job description. On the other hand, maybe you thought your job description was to be a pure coder, when in reality you are expected to do more.

If you're a programmer like me, what would you do?

Get a meeting with your boss and try to clarify the confusion. Clearly, there must be a confusion somewhere, because nobody would think that being taught about Outlook and going to teach people about Outlook is a productive way for you to spend your time.

That said, if you are lacking in the "people skill" areas, then you might benefit from an opportunity to develop them.

But still, teaching Outlook is a real waste of time, it's a really extreme example. The fact that your boss even considered this to be a good idea (and worth the investment of time on an employee) makes me seriously question his intelligence. But then again, managers are not known for being smart.. quite the opposite.

ddanbe commented: Great! +0
mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

I would have to disagree with JasonHippy.. the debugger is not gonna help you in this case.

Even before looking at the code, just by the description of the symptoms, it was very obvious to me that this is a memory issue, and most likely a combination of leaks and uninitialized memory. This means that you were not deleting memory that you've allocated, and that you are accessing memory that you have not allocated or not initialized. This is why the debugger won't help you much, because these kinds of errors are not traceable using a debugger, even with a memory profiler it is really hard to trace, and also because the error is not one thing, it's everything.

After looking at your code (not in details, obviously, because this is a lot to look at), it only confirmed my suspicions. You have an enormous amount of leaks in that code. Are you aware that, in C++, you have to delete anything that you've allocated with new? You allocate objects with new everywhere (far more than you should), and there is not a single delete statement anywhere. This is bound to leak memory all over the place. This is why the program runs for a while but then eventually becomes extremely slow and almost at a stand-still. Also, OS or library protections are sometimes in place to prevent your program from consuming so much memory that it overwhelms the entire system, and usually, these protections will "terminate the program in …

JasonHippy commented: Ooops, I missed that! Good save! +9
mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

I always use "were" in that context. It just sounds more "right" to me (but then again, I'm not a native). I was always curious about this, and whether it was acceptable.

The following is just speculation, but I think it might explain some of the discomfort with this form ("If I were .."). English used to be structured like German, even as late as Old English. It got simplified due to Scandinavian and Norman influences, and lost most of its annoying Germanic inversions and inflections as a result. But there are still traces of Germanic structures, and it still remains kind of acceptable sometimes (it doesn't sound completely wrong). Just think Yoda and the way he speaks (fun-fact: in dubbed-German, Yoda speaks normally). And, under those structural rules, it should be "If I a carpenter was,..." or "If I carpentry to take was,...". The point is, under those rules, the verb does not belong at the third position, after "If" (conjunction), and "I" (subject), as it naturally belongs in the second position, and is thus thrown back to the end of the clause. So, maybe, just maybe, the discomfort is due some innate sense that that verb doesn't belong there (at third position, which comes from the French structural rules, i.e., the "normal" rules).

Does that make me crazy? Possibly... but maybe we're crazy, probably...

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

returning the length of passed string was just me testing, but after mentioning it I will instead return length of string copied to buffer.

Yes, you should follow conventions. Most functions like this return the number of characters (bytes) written on the destination buffer. At least, that's the C convention (the C++ convention is to return the iterator (pointer or otherwise) to the one-passed-last element written), and the C convention is what you need to follow if you are writing a C API function like that.

BTW, the reason that it is convenient to return the number of characters written (like sprintf does) is so that you can do things like this:

void manufactureComplexString(int someOption) {
  char buffer[1024];
  char* p_str = buffer;
  int consumed = 0;

  consumed = sprintf(p_str, "This is just a test.\n");
  p_str += consumed;

  if(someOption & FIRST_OPTION_VALUES) {
    consumed = sprintf(p_str, "First option with value = %d\n", someOption & FIRST_OPTION_VALUES);
    p_str += consumed;
  };

  if(someOption & SECOND_OPTION_VALUES) {
    consumed = sprintf(p_str, "Second option with value = %d\n", someOption & SECOND_OPTION_VALUES);
    p_str += consumed;
  };

  printf(buffer); // print result.
};

The point is, it creates a convenient way to chain operations without having to keep track of too much information. The C++ convention is far nicer, by the way, but hey, if you're stuck with C, you're stuck with C.

Returning the length written is also a convenient way to express that "nothing was done" in case of an error.

I just get …

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

A modest CV is better than no CV.

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

Just install a version of Linux, and start playing around with it. Do stuff in the terminal, write code, write scripts, etc.. It all depends on what you want to do with it (sys admin, coding, etc.).

There are basically two main families of Linux distributions: Red Hat and Debian. That split is where most of the differences are, but there are not too many. On the Red Hat side, you can get distributions like Fedora (and its variations "spins") or other derivatives. On the Debian side, the main family is Ubuntu and its derivatives. Frankly, any of them will do, Linux is pretty similar between distributions or family of distributions. Think of different distributions as different "flavours" of Linux, because under-the-hood they are all nearly the same. I suggest you just research around a bit and see screenshots / feature-lists to figure out which distributions might be best for your taste, and then just try one, or a few.

You can first try out different distros by installing them in a VirtualBox. But, ultimately, you really should do a dual-boot installation with the distro that you prefer.

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

That also means all you young folks would never get jobs because there were so many old people still working.

If the retirement age was 950, then you would also be part of the "young folks". They would say: "Pfff, he only got gray hair like a couple of decades ago.. he's almost an infant."

Earth of already overpopulated, what would it be like if the life span were doubled or trippled?

My guess would be that there would have to be severe population control, i.e., the number of children would have to limited severely (and I can't imagine how you would have to go about doing that, like sterilizing most people and stuff like that). That's the sad part of this "living 1000 years" thing, is that there won't be much children around, and not many people "allowed" to have children either. That would take away one major factor of purpose and fulfillment, not to mention that it would be boring if only adults existed (would we still have amuzement parks, and stuff?).

Reverend Jim commented: The new motto would be "don't trust anyone over 500". +0
mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

Following up on a discussion on this thread, I did some tests on the performance of recursion vs. iteration, and some interesting things happened, so I thought I would share the results. I'm gonna structure this a bit like a lab-report, because that's really the best way to put it. But I hope the discussion can continue on additional ideas or insight into the performance issues that are discussed here, or if you disagree with my analysis.

Experimental Method

So, I took Schol-R-LEA's coin-combination example as a test case, and timed the execution of three different versions: recursive, iterative with dynamic allocation, and iterative with VLA (stack-based arrays) (because of this discussion). Here is the code:

#include <vector>
#include <utility>
#include <chrono>
#include <iostream>

// recursive version
int count_combinations_rec(int sum, const int* coins) {
  if (!*coins || sum < 0) 
    return 0;
  int result = count_combinations_rec(sum, coins + 1);
  if (sum == *coins) 
    return 1 + result;
  else
    return count_combinations_rec(sum - *coins, coins) + result;
};


// equivalent iterative version (shared by other two functions):
template <typename TaskIter>
int count_combinations_iter_impl(TaskIter first_task) {
  TaskIter cur_task = first_task;
  int result = 0;
  while( cur_task >= first_task ) {
    const int cur_sum = cur_task->first; 
    const int* const cur_coins = cur_task->second;
    if( !*cur_coins || (cur_sum <= 0) ) {
      --cur_task;
      continue;
    };
    ++(cur_task->second);
    if(*cur_coins == cur_sum)
      ++result;
    else {
      ++cur_task;
      cur_task->first = cur_sum - *cur_coins;
      cur_task->second = cur_coins;
    };
  };
  return result;
};

// iterative version with dyn-alloc
int …
Moschops commented: Thanks Mike. This sort of practical knowledge about the tool is always good to know and make me look far for competent at work than I really am. Much appreciated :) +11
Ancient Dragon commented: Great job :) +14
mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

What do you get when D is close to 0?

When D is close to zero, you get close to an under-determined case and you have to switch to a minimum-norm solution. When the determinant is zero, the matrix is called rank-deficient (row-rank), in mathematical analysis. In numerical analysis, however, we generally talk about the numerical rank or the condition number (the ratio of the highest eigen-value divided by the lowest eigen-value, in absolute values). The numerical condition number has, in general, a direct effect on the amplification of the numerical round-off error. Any operation inflates the round-off error, it's just a matter of how much. In a linear system solver, the round-off error on the input is, at best, multiplied by a factor proportional to the condition number of the matrix, e.g., if the condition number is 1000 and the error on the input is 1e-6, then the error on the output (solution) is roughly 1e-3. So, if the condition number is too high (e.g., the determinant is near to zero), the whole calculation is meaningless because the error is larger than the value, meaning that the solution is garbage. This is why it is important to worry about this. Also, some algorithms are worse in terms of round-off error amplification. For instance, the determinant method produces terrible errors (the amplification factor is the square of the condition number, if memory serves me right), while a more decent method like QR or RRQR achieves the …

Paul.Esson commented: Informative ! +4
mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

Yeah, but I mean only programmed code.

That's your mistake right there, you cannot control or restrict the means by which attackers attack. It's like your asking if it is possible to build an unbreakable wall to keep intruders out, while in reality, intruders will get in either by a tunnel under the wall, climbing over the wall, getting through the door or window, trying to look through the wall, piggy-backing on people who are allowed to cross the wall, etc... the point is, the strength of the wall has no bearing on the overall security, as long as there are weaker loop-holes around it.

On the basis of program hacks themselves (e.g., software exploits, encryption-breaking, etc.), the security has become very solid overall, but that only means that attackers don't attack that line of defense as much as other weak-points. The biggest myth about hackers is this impression that all they do is exploit software loop-holes and get into computers or networks programmatically. For the most part, they don't, at least, for those who are interested in the gain ($), as opposed to the technical challenge.

In terms of hacking code, yes, anything is breakable, with enough time, skill and knowledge. For most stuff, the hardest part is reverse engineering it, but everything can be reverse engineered, and then, exploited. But at some point, the investment (time, money, resources) required to break the system that way is far too much that nobody will choose to break the …

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

You might want to look at the Wisdom of Chopra, which is a random quote generator from a database of mumbo-jumbo terms collected from the non-sensical tweets of Deepak Chopra (the meta-physics "guru"). They say you can contact them to get the sources.

I think that generating natural language is a very difficult topic, depending on the level of sophistication. It really depends on how much effort you want to put into forming complex grammatical sentences (as opposed to very simple "subject verb complement" forms), and if you want to actually have meaningful sentences (as opposed to just random, but grammatically correct, sentences). On the grammar side, you really want to look into linguistics, especially generative grammars, and there are libraries out there that can help you in this regard, like Boost.Spirit (which has grammar construction, parsing, and generation, in one unified set of DSEL C++ libraries). As for meaning, that's a whole different ball-game, and I would only have a vague idea of where to start. There are also ways to mimic meaning, drawing from machine learning concepts, such as predictive modeling and expectation-maximization (EM) algorithms, like for example, scanning databases of written work (books) and drawing correlations between words and their likelihood of being found together in sentences and stuff, such that you can generate sentences that kind of make sense (e.g., you are more likely to generate "a tree with green leaves" than "a car with blue leaves").

The problem really …

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

Seeing how my nephew and niece (3 and 2 years old, now) are developing, it is pretty clear to me that consciousness is something that develops as higher-order thinking develops. It's clearly a product of the brain's development. As you see an infant develop from being a kind of instinctual automaton that cries when hungry, that sleeps when tired, that giggles when stimulated by sounds or funny faces, etc.., to becoming aware of its actions, aware of other people, aware of the passing of time, able to imagine scenarios, and so on.., you are looking at the development of consciousness right there, and it's a beautiful thing. And this natural process is beautiful enough in my opinion, I don't see a reason to want some additional cosmic explanation for it, it spoils the extraordinary beauty of what consciousness really is.

iamthwee commented: Wow +0
mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

I was looking around the web to try and find a code that that does the same as the stdafx, but I did not find any.

You will not find any, because other compilers do not need it. The stdafx header does not provide anything more than some MSVC-specific things that prepare your headers for being pre-compiled. Other compilers implement pre-compiled headers differently, mostly through compiler options (command-line options) instead of stdafx. In other words, you will never need that header on any other platform / compiler. So, don't look for a replacement, just forget that it exists, and take it out of any code that you have.