| « Prev | Page 1 | Page 2 | Page 3 | Next » |
|
I'm not going to lie, though I'd never append a null to the end of a string just for shits and giggles, programming in C++, especially with third party libraries, is often an exercise in frustration with regard to pointers, and the path of least resistance is to just try each pointer/object operator and go with whatever compiles properly.
|
Re: Lucky Pointing
2012-07-24 09:14
•
by
Sebastian Buchannon
(unregistered)
|
actually no |
|
Something is fishy here. That code wouldn't make it past the type checker.
|
|
So what's the problem then?
;-) |
Re: Lucky Pointing
2012-07-24 09:25
•
by
TheSHEEEP
(unregistered)
|
Disabled warnings. :D |
|
That code is valid C++ assuming that Buffer is a member variable of type char *.
The real WTF is that they are implementing their own string class, albeit that what they are trying to do there is not possible with std::string which has no function to return you a writable buffer. However that is still a WTF as they should at least interpret it internally as a std::vector<char> The +'\0' is stupid, of course but the compiler probably just strips it out. Of course it will not put a null terminator on the end of your array. Doing so would be wrong anyway. What would happen if you call this multiple times? |
Re: Lucky Pointing
2012-07-24 09:44
•
by
Cbuttius
(unregistered)
|
You probably won't get a warning here though. You normally get a "possible loss of data" when converting from a larger integral type to a smaller one but converting from char to int does not risk any loss of data. |
|
Depending on how -> and + are overloaded, this might indeed do exactly what the programmer intended to do...
|
Seriously? I always thought that C++ is precisely the type of language where you can shoot your self in the foot spectacularly with such attitude. I mean like
|
|
TRWTF is returning char* not const char*, right?
It seems an odd representative line to me. The compiler almost certainly just drops the +0 operation as redundant and it all works fine. Yes, the author clearly didn't get it, but this is pretty common with part-time or new c++'ers. Operator overloading is pretty evil in general, but this would have been more useful generally with: const char * String::operator const char *() { return buffer; } (or even char *) |
Actually...
|
|
|
I love pointers so much! And strings!
But indeed, when you don't master it, it can lead to big WTF!! Like this one... Or like some in the code I have to maintain... |
Re: Lucky Pointing
2012-07-24 10:32
•
by
History Teacher
(unregistered)
|
...are you the author of this particular representative line, by any chance? TRWTF are coders who don't understand pointers, yet touch any language less separated from hardware than crossplatform HTML+javascript. |
No. Oh, I understand pointers, but they are too easy to muck up, especially with C++'s Byzantine syntax, and an object-oriented language offers enough tools to pretend that pointers do not exist (such as Java does). Unless you're doing serious low-level or high-performance computing, there isn't much use for pointers. |
|
Seeing that attempt at "string concatenation" leaves me with the feeling that Benedikt's predecessor may have been a Java programmer.
Of course, TRWTF is C++. It could have been an elegant and simple object oriented superset of C, but instead it's a glorious example of how not to design a programming language. In fact, I'm not entirely sure this is a joke: http://www-users.cs.york.ac.uk/~susan/joke/cpp.htm The other RWTF is Akismet |
Re: Lucky Pointing
2012-07-24 10:48
•
by
Dave-Sir
(unregistered)
|
You won't get any warning, but not for the reasons you state. The type of '\0' is int. Assuming buffer is a pointer to char, adding an int to a pointer is a perfectly valid operation, and not worthy of a warning. It reminds me of some code I encountered some years ago. To test fo an odd number, the following code was used: if (value&1 == 1) <etc.> However, because of precedence rules, this gets parsed as if (value & (1==1)) But it still works. Just not the way the original programmer thought. |
Re: Lucky Pointing
2012-07-24 10:53
•
by
RandomUser423718
(unregistered)
|
BOCTAOE When referring to "physical memory" pointers, maybe. However pointers, as a concept, are important for understanding any number of common patterns, such at those that appear in relational databases (primary/foreign keys), etc. |
|
Calling a pointer a reference doesn't mean it is not a pointer.
Java has pointers. They call them references and use . syntax instead of -> but they have the semantics of pointers. You don't have to delete them because Java has automated garbage collection. That is why if you don't assign one to anything then try to use it you get a NullPointerException. Remember that C++ was originally a layer on top of C that brought in some concepts from other OO languages that were there at the time, and one of the main important things supported is RAII which essentially means cleaning up through objects' automatic destructors. That is why, if you use the string class, you don't have to mess about with pointers. But yes, you can integrate with C easily which means if there is a library in C you can just use it. So sometimes you need to get a C string out of your "managed" classes. If you want a contiguous writable buffer you should use vector<char> underneath, not std::string. The overload of operator+ in my example was a bit of a joke though. If you are going to give it operator+ it should have the proper semantics of that operator so.
Yes, operator+ returns a new object and leaves the old object in an unchanged state. As long as you obey the spirit of the rules of operators when you overload them, users of your class won't get into trouble. It is true that doing the above a lot will be inefficient but then you won't be doing that as to build strings you use ostringstream. |
Precedence? WTF is precedence? That looks like a Very Big Word. I should not have to know it. I should not have to know anything. The computer should just do what I want. Programming languages are TRWTF. Nobody wants to type commands. So boring. And hard, dammit! There should just be a big round candy colored button and when I click it, it reads my mind and Just Works. If you can't design something to cater to my fantasy, you are no good. |
|
Perhaps I misworded what I said. What I meant was compiles properly, and exhibits the desired behavior. If it doesn't exhibit the desired behavior, then I wouldn't say it compiled properly, it just compiled. :p
|
Re: Lucky Pointing
2012-07-24 11:20
•
by
¯\(°_o)/¯ I DUNNO LOL
(unregistered)
|
Rolling your own String class? Oh wait, I know... it needs a regex! Actually, TRWTF is operator overloading. |
As opposed to a colleague of mine at a previous job of mine, who had been doing too much work with JavaScript. So, to present a message like "Elements found: {number}", he would exploit JavaScript's unnatural fascination with automatic type conversions: var value = calculationFunction( parameters ); This doesn't work so well in C++. |
|
This code is painful to look at on so many levels. TRWTF is that, given the pointer from this function, the calling code can mess with the data in the object without, presumably, any data length or integrity checking.
Encapsulation? We don't need no stinkin' encapsulation! |
|
Heh. It's so rare for us to see C++ WTFs on this site that when one is finally posted, most of the comments focus on generalities about the language itself.
|
|
I love Stroustrup's quote:
"There are only two kinds of languages: the ones people complain about and the ones nobody uses." |
Sadly, there's a lot of odd code that a C++ compiler will happily compile:
|
|
This one brings to mind adages such as "there's never time to do it right but there's always time to do it over", or more succinctly "measure once cut twice; measure twice cut once".
The problem is that people get nervous about the idea of trying to do something properly (in this case checking the types). But the prospect of guessing and hoping seems less nervous. It seems back-to-front, but it's not surprising if you follow a rule of higher risk -> lower outlay. Since writing software seems risky to such people, they minimise their outlay i.e. the amount of time they spend on the first coded version. Of course, experience of doing it the "right way" would help them realise that they can drive down the risk by using good processes. |
|
Using the null character to denote end of string has its advantages but can be a WTF at times.
Prefixing the length means it is faster to calculate the length of the string but makes it less maintainable. Firstly the potential length of the string is limited by the length of its header, and secondly when you modify the string you have to modify this length. In addition, there is the method of "tokenising" a string that into lots of strings by modifying the "separator" character into a null, allowing each component to be a string on its own. In fact sometimes you use a double zero to indicate the end of the sequence. Of course for binary "blobs" there will often be embedded null characters but in general these are not modified or lengthened the same way strings often are. The real WTF with C++ and strings is that the standard string is: 1. really a typedef of template basic_string<char, char_traits<char>, allocator<char> > 2. No standard ABI so if your library uses std::string in its interface it isn't guaranteed to work with a different library that uses a different compiler. It wasn't that long ago that you couldn't even pass a std::string between DLLs / shared objects built with the same compiler. All of which leads to you finding lots of "own implementations" of string, especially in legacy code. Of course, legacy code is still around because people still use these projects that are being maintained and they brought in enough money to the business. |
|
I'm surprised no one said:
"First\0" |
That's been tried. It's called Objective-C, and it's such a smelly pile of WTF that no one uses it unless Apple is stuffing it down their throats. Is it even possible to create an elegant and simple superset of something that it itself neither elegant nor simple? C++ may be a glorious example of how not to design a programming language, but it got half of its mess from C and most of the other half is hacks to try to make it possible for higher-level concepts to integrate properly onto the existing C foundation. |
|
TRWTF is rolling out their own string implementation.
You know, as if C++ doesn't have enough of these already. |
Re: Lucky Pointing
2012-07-24 12:17
•
by
Cbuttius
(unregistered)
|
Because in C++ you start counting from 0. So the first post should read: 0th... |
Re: Lucky Pointing
2012-07-24 12:17
•
by
Asdlarfgs
(unregistered)
|
How... how is that "exploiting JavaScript's unnatural fascination with automatic type conversions"? That's just the natural way to do it in most dynamic languages. |
Re: Lucky Pointing
2012-07-24 12:21
•
by
Cbuttius
(unregistered)
|
It depends if they actually do need to get a char * out of it (rather than a const char *) in which case you can't do it with std::string. But in this case your implementation should use std::vector<char> underneath and not raw pointers. However if you handle a lot of very short strings, there is an advantage in using a "local" member class buffer to handle short strings rather than allocate as allocations are expensive. In such a case you will probably have a member function to get the data buffer. |
I hired a contractor to do some remodeling and learned, to my great dismay, chagrin, and expense, that his philosophy was "measure zero, cut three times". He actually installed a door frame, forgot to account for the thickness of sheetrock, tore it out, installed it again a half inch down, realized he forgot to account for the trim, tore it out again, installed it again, and it was still wrong. I forget why this time. I wanted to fire him but he had me by the balls. That part, he was really good at. Years later, I still curse his memory every time I walk down my crooked hallway. He also left me with a ceiling that slopes, and a roof that doesn't. All because he was fundamentally averse to a measuring tape and simple addition. Remodeling is hell. Stay as far away as you can. |
|
It would be amusing to run the source code through PC-lint, and see just how many other issues like this are lurking deep in the code.
|
|
TRWTF is people complaining that a language "lets you shoot yourself in the foot". A gun will let you shoot yourself in the foot, much like a hammer will let you smash your thumb and a saw will let you cut your fingers off. C++ is a tool like any other and will cause a bloody mess if used without proper training or care, or if used in an inappropriate situation.
You wouldn't use a chainsaw to slice a lemon in a cramped kitchen, nor would you use a carving knife to cut down a tree. C++ is no different - it has its place and where it is used appropriately it is positively unmatched. Likewise, when used inappropriately it'll cause massive amounts of bloodshed. The same can be said for just about any language. Deal with it. |
I actually like Objective-C, since it essentially combines my two favourite programming languages - Smalltalk and C. Compared to C++ it feels much more intuitive once you get past the culture shock of seeing so many square brackets.
I'd argue that C++ is largely a WTF of it's own making, since it's not a strict superset of C so it can't really blame it's forebear, and got a lot of things wrong in the object model and the standard library. I'd have preferred virtual methods by default, and for dubious "experiments" such as vectors of bools to have not made it into the standard. That's just scratching the surface - for more WTF'ery, refer to the Exceptional C++ and Effective C++ books. |
|
Buffer could very well be a class that has overloaded the plus operator. The real WTF is operator overloading so that you can never really know what is going on.
This is just more postings by code snobs. Come on, let's get back to the really gross stuff and stop complaining about people's syntax. :-[ |
Some of us can think faster than the code compiles. |
Re: Lucky Pointing
2012-07-24 13:43
•
by
jMerliN
(unregistered)
|
TRWTF is operator overloading. When the language constructs are user-defined, everything is WTF. |
Re: Lucky Pointing
2012-07-24 13:48
•
by
n_slash_a
(unregistered)
|
Well stated. This is why a good company (should) hire engineers and not half-trained monkeys. |
We need a 'like' or thumbs up button in here |
I disagree. There are plenty of useful things you can do with operater overloading. Performing math on data types so you can add matrices together with operaters. Its up to the programmer to be smart about it and implement it in a sensible way (and document it) |
Re: Lucky Pointing
2012-07-24 14:46
•
by
danbruc
(unregistered)
|
That's not true. In C# there is a single thing you can do with a reference - dereference it. A reference is either a null reference or a reference to an object of its specific type. You are neither allowed to use pointer math to point to the interior of an object or to random garbage in memory, nor are you allowed to cast a reference to an arbitrary type without generating at least an invalid cast exception at runtime (unless the cast is valid of course). |
Re: Lucky Pointing
2012-07-24 15:08
•
by
Harrow
(unregistered)
|
Two null terminators indicates the end of a string list or the end of a paragraph. Three nulls indicates the end of a document or file. Four nulls is end of directory, Five nulls is end of transmission or end of volume, and six nulls stands for the end of the working day. Seven nulls marks end of current employment. Eight nulls means time to retire and collect SS. Nine nulls specifies the end of the world as we know it. So calling it a few extra times may generate errors, which will probably be recoverable, but if you call it inside an infinite loop, it's curtains for all of us. Please use null terminators responsibly. -Harrow. |
But is there anything you can do with operator overloading that you can't do without it? Y'know, other than making your code harder to decipher for maintenance programmers? Operator overloading always seemed like self-indulgent syntactic sugar to me. |
Re: Lucky Pointing
2012-07-24 16:17
•
by
jMerliN
(unregistered)
|
Your analogies are flawed. Any Turing complete language can let you shoot yourself in the foot. See: algorithmic complexity, bad code, etc. You compare a tool to a tool that has hidden tool-altering features that are invisible except on extreme introspection. The kind of "shoot yourself in the foot" C++ brings to the table is more like selling a gun to people and making it such that any person can modify where the bullet exits in a non-obvious manner (such as, it still looks like a gun but when you pull the trigger, it shoots directly at your feet). Then whenever you pick up a gun you haven't been the sole-owner and sole-possessor for its lifetime, you can't ever for sure know when you pull the trigger that it's not going to shoot your foot, unless you take it apart. Oh, and C++ also lets you universally modify how guns work, so anyone can just change how they fire, so now you have to deconstruct the entire universe to figure out if your gun will shoot you in the foot when fired. That's the WTF of C++. Changing the language's behavior in a manner that isn't immediately apparent without further introspection. And this breeds WTFs not present in other languages: APIs designed to be used via overloaded operators, so that there's not a well named function you can call to do a task (and thus avoid the use of operators with non-primitives, and again, you can overload operators on primitives, too, which is a whole other world of WTF). Things like needing to call myObj.operator++(...) explicitly to increment something because there's not a myObj.increment(). People do this. The very existence of this terrible feature leads to feature abuse and then feature reliance. We don't have the issues this "feature" causes in other languages. When we see code pasted in StackOverflow, we know what it does, not what it should do given the default operators. It's more like a hammer that has the "feature" of being able to have an invisible spring attachment so that when you hammer a nail, the hammer flies back into your face. It's not just a regular hammer, it's now an overloaded hammer, and one can argue the merits of such a hammer (two nails at once, if you position them right), but at the end of the day, it's still a massive WTF. It's novel, sure, but that doesn't make it any less of a WTF. |
| « Prev | Page 1 | Page 2 | Page 3 | Next » |