wtorek, 29 grudnia 2015
Fast conversion of floating-point values to string
The conversion to string could be 15 times faster than sprintf. Read more...
niedziela, 27 grudnia 2015
Base64 encoding — implementation study
Although base64 encoding is a very basic algorithm, it could be sped up a little (25% sounds good?) Read more...
sobota, 26 grudnia 2015
Benefits from the obsession
Everything has started few years ago when I found John Regher's blog. If
you don't know the blog I highly recommend it. Among other things (I like
the photos!) the author studies bugs in compilers, undefined behaviours and
similar things. The word "overflow" appears quite often in his posts due to
the great number of errors related to improper use of the integer
arithmetic. Well, I don't know when the obsession has exactly started, but
recently I realized that I am alert of all integer operations in my
programs. Read more...
sobota, 28 listopada 2015
Implicit conversion - the enemy
I wrote:
I forget that pad_left signature is string, int, char and the char parameter has a default value. My mistake, without doubts.
This is another example of dark sides of the implicit conversions. C++ converts between characters and integers seamlessly. These two beast are distinct in the nature. Of course characters are represented by the numbers, however it's an implementation detail.
One can say: you made a mistake and now blame the language. No, I blame language's design. I'm afraid that we end up with something like Integer and int to overcome such problems.
Lesson learned: never use default parameters in public API (surprise!)
result += string_utils::pad_left(string, '0');
I forget that pad_left signature is string, int, char and the char parameter has a default value. My mistake, without doubts.
This is another example of dark sides of the implicit conversions. C++ converts between characters and integers seamlessly. These two beast are distinct in the nature. Of course characters are represented by the numbers, however it's an implementation detail.
One can say: you made a mistake and now blame the language. No, I blame language's design. I'm afraid that we end up with something like Integer and int to overcome such problems.
Lesson learned: never use default parameters in public API (surprise!)
niedziela, 22 listopada 2015
Another C++ nasty feature
I'm fond of C++ weirdness, really. This language is full of traps, and it shocks me once in a while.
Let's look at this piece of code, a part of a larger module:
We would expect that in case of an error following line will be reported: "user has entered wrong time: 123 PM". Obvious. But please look closer at the code, do you see any mistake? There is one... dirty... hard to notice. I'll give you a minute.
So, the mistake is lack of comma between expressions *clock_hour and *am_pm_clock. However, the code is valid! It compiles! And it took me a little longer than a minute to understand what happened. Explanation is:
In result method is called with a single parameter of type cont char*.
It's bizarre, it's terrible. A language should help a programmer. In my opinion implicit conversions is the worst feature of C++.
Let's look at this piece of code, a part of a larger module:
void validate_date() {
// ...
boost::optional<unsigned> clock_hour;
boost::optional<unsigned> am_pm_clock;
// ... fill these fields
if (some sanity check failed) {
report_error("user has entered wrong time: %d %s",
*clock_hour
*am_pm_clock ? "AM" : "PM");
}
}
We would expect that in case of an error following line will be reported: "user has entered wrong time: 123 PM". Obvious. But please look closer at the code, do you see any mistake? There is one... dirty... hard to notice. I'll give you a minute.
So, the mistake is lack of comma between expressions *clock_hour and *am_pm_clock. However, the code is valid! It compiles! And it took me a little longer than a minute to understand what happened. Explanation is:
- *clock_hour evaluates to expression of type unsigned;
- then compiler sees * - a multiplication operator;
- so checks if multiplication of unsigned (on the left side) with boost::optional<unsigned> (on the right side) is possible;
- it is, because boost::optional<T> has conversion operator to type T.
((*clock_hour) * unsigned(am_pm_clock)) ? "AM" : "PM"
In result method is called with a single parameter of type cont char*.
It's bizarre, it's terrible. A language should help a programmer. In my opinion implicit conversions is the worst feature of C++.
niedziela, 15 listopada 2015
Short report from code::dive 2015
Few days ago I attended code::dive 2015, an IT conference in Wrocław, Poland. It was a one-day conference with a great number of presentations. There were four stages and five sessions, in total 20 talks. Impressive number! But an attender had to choose his own path of just five lectures. I think the decision was pretty difficult. Sometimes less is better. Read more
środa, 15 lipca 2015
C++ magick
A programmer wrote:
Do you see the mistake? Programmer assumed that expression "Invalid index: " + index evaluates to std::string("Invalid index: <some number>").
In fact type of expression "Invalid index: " is char[15], so char[15] + integer results in --- more or less --- char*. For index in range [0, 15] exception will carry tail of the message; for example when index=10 then it will be "dex: ". But for indexes larger than 15 and less than 0 program likely crash.
This is why I hate C++, the language has many dark corners, stupid conventions, implicit conversion, not to mention UB ("just" 150 UB, if you're curious).
class container;
class IndexOutOfBounds {
public:
IndexOutOfBounds(const std::string& msg);
};
void container::remove(int index) {
if (index < 0 || index >= size()) {
throw new IndexOutOfBounds("Invalid index: " + index);
}
// the rest of method
}
Do you see the mistake? Programmer assumed that expression "Invalid index: " + index evaluates to std::string("Invalid index: <some number>").
In fact type of expression "Invalid index: " is char[15], so char[15] + integer results in --- more or less --- char*. For index in range [0, 15] exception will carry tail of the message; for example when index=10 then it will be "dex: ". But for indexes larger than 15 and less than 0 program likely crash.
This is why I hate C++, the language has many dark corners, stupid conventions, implicit conversion, not to mention UB ("just" 150 UB, if you're curious).
Subskrybuj:
Posty (Atom)