Dennis Ritchie: the giant whose shoulders we stand on

Because of him I earn my bread now. (despite I did not like his C book)
isn't it something like cout<<"RIP, dmr. \n"; btw? or am I mixing up C with C++ up again? Ah too long ago. Now it's only C# this and Java that...
 
You may be mixing him up with Bjarne Stroustrup, who invented the C++ language and wrote books about it as well (I have his book, and ya, it's not something you want to read from cover to cover but boy is it thorough!). The C language (popular on the Amiga, and how I got into it) does not support streams, so cout<<"blah"; would cause an error.

And for the record, even though I prefer C++ over C, I never did like IO streams. At least not for printing stuff to the console. It's more useful when overloading an operator in a class so you can serialize objects. But then, I also dislike operator overloading! :p
 
No, I remember again, that was indeed C++. I got the orange/white C handbook. (the book I did not like)
I mix up all these C derivatives nowadays :(
 
And for the record, even though I prefer C++ over C, I never did like IO streams. At least not for printing stuff to the console. It's more useful when overloading an operator in a class so you can serialize objects.

+1

I almost always use C style IO for any form of formatted output.

But then, I also dislike operator overloading! :p

I have found it very useful, particularly when dealing with numerics involving vectors and the like. Seeing such stuff expressed algebraically to me is way more natural than seeing explicit method call, no matter how descriptive the names.

However, it is certainly a feature of the language that is ripe for abuse, which puritanical Java developers loved to point out in language wars of old. They can take a running jump, of course, as StringBuffer implements operator + for concatenation since forever and they never mention that...
 
Ya I can agree with that. It's certainly a useful tool in some cases. But can also cause some serious headaches. One issue I have with it is that it's really hard to track down code that uses the overloaded operator. If you for instance overload the + operator for intergers, well, it can be tricky to find which + operations use the built in one or your overload. I once had to refactor a class that had public operators. I was pretty sure that nothing in the entire code base used them, but couldn't think of a quick way to prove that. I ended up removing the implementation (leaving the public interface in the header untouched) and doing a full build. No linker errors proved that they were not used (simply removing them from the headers would have caused the default operator to kick in). But that's a real PITA when it takes over 40 minutes to rebuild! I suppose better IDEs could properly find references, but I didn't trust VS2005's abilities in that regard.
 
references!!! *spit*
nice enough idea, I suppose, to save some typing but... when you call func1(thing) and func2(thing) and one of them changes your thing ... yes, you can go look at how func1&func2 are declared but it should be obvious from the call and it isn't.
 
Ya. I tend to prefer:
void ack(const object& cref); // when the object is not modified
void ack(object* ref); // when the object is modified

Although really, when changing the object you should have a good reason why you're not doing:
object.ack();
 
Although really, when changing the object you should have a good reason why you're not doing:
object.ack();

The older a code-base gets the more likely it is that "good reason" will at some point include pulling someone out of the slums of Hyderabad an yelling that you need something to work by the end of the day and don't worry, we'll fix it up and do it properly after we ship.
 
I just came here to post about this fellow because I figured you guys would know him.....so I'm not surprised you are all geeking over "C" and the like.

RIP Mr Ritchie

continue unabated......
 
references!!! *spit*
nice enough idea, I suppose, to save some typing but... when you call func1(thing) and func2(thing) and one of them changes your thing ... yes, you can go look at how func1&func2 are declared but it should be obvious from the call and it isn't.
Heh, indeed, pointer-like issues all over indeed. But isn't it also an anti-pattern to alter attributes?Shouldn't you rather spit on that instead?
Anyway, I'm most interested in what aspect oriented programming has to offer, as it seems to me, with that, you can deal such things much more structurally.
 
References in C++ have their place and function arguments often isn't it (compared to regular pointers, that is). However, being able to return a reference is very important in the implementation of many containers. Bear in mind that although a reference behaves like a self-dereferencing pointer, it isn't and can be optimized by the compiler out of existence - very important for efficiency, especially when the compiler is generating templated code.
 
References in C++ have their place and function arguments often isn't it (compared to regular pointers, that is). However, being able to return a reference is very important in the implementation of many containers. Bear in mind that although a reference behaves like a self-dereferencing pointer, it isn't and can be optimized by the compiler out of existence - very important for efficiency, especially when the compiler is generating templated code.
I won't even begin to argue with you there - merely saying that you should never ever ever, in a code language, let one thing to look like another thing. In a human language it can provide hours of merriment from puns to innuendo to poetry - but in code it isn't funny. Code is read much more often than it is written - and it's often written by the lowest bidder.
 
You mean it can't be optimized by the compiler out of existance?
No, the compiler can optimize the reference out of existence (obviously that depends on the circumstances of the code being generated, but in template code, it happens quite a lot), particularly when it's a temporary in some template generated operation. That is to say, it can do away with the temporary reference as a handle to something else when performing all manner sub-expression elimination and so on - essentially whatever is operating on the reference is actually operating directly on the physical instance the reference was bound to. That may not always be possible for a regular pointer since dereferencing may have side effects.
 
I won't even begin to argue with you there - merely saying that you should never ever ever, in a code language, let one thing to look like another thing. In a human language it can provide hours of merriment from puns to innuendo to poetry - but in code it isn't funny. Code is read much more often than it is written - and it's often written by the lowest bidder.
Ah, the idea that programming will become much more configuration...
I like it! I had to spend way to much time to create awefully redundant code in (g)ASP
Microsoft's ASP ->:whip:<- me
 
Ya. I tend to prefer:
void ack(const object& cref); // when the object is not modified
void ack(object* ref); // when the object is modified

Although really, when changing the object you should have a good reason why you're not doing:
object.ack();

Actually, non-member helper functions are occasionally a good way of avoiding fat interfaces in some cases. Also, not all possible functions (in C++) can be member functions of your class. This applies in particular when dealing with operator overloading For example, you may be using operator overloading to create some sort of intuitive (particularly for numerics) operator based usage syntax for your types. Following the general rules for encapsulation suggests that only member operator methods should be mutators. So, implementing operator+=() in your class makes sense, but implementing operator+() can be done as an external that uses it. Off the top of my head:

Code:
class MyClass {
  public:
    MyClass& operator+=(const MyClass& other)
    {
       // Do whatever addition entails here....

       return *this; // return reference to self to allow chaining expressions (aka fluent)
    }

    // ... more code for fun and profit
};

MyClass operator+(const MyClass& a, const MyClass& b) // non-member helper function
{
  MyClass c(a); // this assumes copy construction
  a+=b;         // invokes member function MyClass& MyClass::operator+=(const MyClass&)
  return c;     // note - returning by value, since reference would be really bad here...
}

When implementing non-trivial concepts where operator overloading is used, you might find you need to overload binary operators that will take two different types and doesn't neatly fit into the class interface of each. Implementing these as pure external helper functions is usually the right choice (assuming you don't hold operator overloading to be the devil's work, but the same often applies even if you exchanged the operators with regular names).
 
I won't even begin to argue with you there - merely saying that you should never ever ever, in a code language, let one thing to look like another thing. In a human language it can provide hours of merriment from puns to innuendo to poetry - but in code it isn't funny. Code is read much more often than it is written - and it's often written by the lowest bidder.
What Fluffy said. Here's a neat little article all programmers should read every now and then: Making Wrong Code Look Wrong
 
Back
Top