C++ rant - lack of developer friendliness is poor design

Pages: 12
So I'm 33 and tinkering with C++ because it's the de facto language of my industry, but I'm continually frustrated by how difficult simple tasks are. I understand that the design of the language was based on speed over everything, but there is no reason a language this widespread and well-developed shouldn't have more tools for a beginner.

Although there have been many examples, my current beef is turning the current time into a string. This should be something as easy as:
string theCurrentTime = time::getLocalTimeAsString();

instead I get examples like this:
http://msdn.microsoft.com/en-us/library/a442x3ye.aspx

which is absolutely ridiculous. I won't post the code here, but going line by line I would need to understand the following things to understand what that code is doing:

--create a structure for a new "tm" object, which requires knowledge of that library
--create a character array
--create a __time64_t object
--use the _time64 method, and know that I have to pass it the address of the __time64_t variable, which basically requires a complete knowledge of passing by reference vs passing by value

--run the _localtime64_s function with the "tm" structure and __time64_t objects as parameters

--manipulate the string using the string copy functions to change "am" to "pm"

--convert it to an ASCII representation using the asctime_s function, which requires the character buffer, character buffer's length, and address of the "tm" structure

--and then the thing that really sets me off, the example uses the line:
printf( "%.19s %s\n", timebuf, am_pm );
which I can barely even figure out even after looking at
http://www.cplusplus.com/reference/cstdio/printf/

so I think that's something about formatting the string to 19 characters and putting a newline at the end of it. But why anyone, developer or beginner, should have to count how many characters are in the string just to print out the time is absurdly tedious.

Speaking a little more broadly, and this is colored by the fact that I recently read the biography of Steve Jobs, this is such poor design. This functionality was written by elitists who've forgotten that not everyone has been writing C++ programs for a decade. And if I add in the fact that the VisualStudio version was giving me an error message 4996 when I was using a simpler example, but that the MS docs for that error message couldn't point me to an easy-to-use fix for that problem, it's an example of how Microsoft is failing to deliver a product that is easy to use.

In summary, this is one example where doing a simple task in C++ requires way more knowledge than should be necessary. I should not need an in-depth understanding of the C++ time libraries, the differences between passing by reference and value, and the archaic formatting options of the printf function to get the local time.
http://www.cplusplus.com/reference/ctime/ctime/
You could do something like
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <ctime>
#include <iostream>
#include <string>

std::string getCurrentTime()
{
    std::time_t currentTime;
    std::time(&currentTime);
    return std::string(ctime(&currentTime));
}

int main()
{
    std::cout << getCurrentTime() << std::endl;
}
but there is no reason a language this widespread and well-developed shouldn't have more tools for a beginner.


Few languages have more tools than C/C++. The difference between them and languages like Python/C#/Java is that the libraries are not distributed with the compiler. Partly because there are so freaking many of them.

printing the current time with wx is about as trivial as you think it should be:

1
2
3
// note I didn't test this, this is just what I gathered from documentation:

cout << wxDateTime::Now().Format();



--and then the thing that really sets me off, the example uses the line:
printf( "%.19s %s\n", timebuf, am_pm );
which I can barely even figure out even after looking at
http://www.cplusplus.com/reference/cstdio/printf/


That's C, not C++. And yes... printf and C in general is very cryptic and hard to use... I agree.

But why anyone, developer or beginner, should have to count how many characters are in the string just to print out the time is absurdly tedious.


Again this is more gripes with C, not with C++.

And I agree with you. I don't like coding with straight C. It's absurd.

This functionality was written by elitists who've forgotten that not everyone has been writing C++ programs for a decade.


Well... it's more that it's because it's C, not C++ =P

If you're going to complain about a language.. make sure you pull your examples from the right language.



EDIT:

Nice catch @ giblit.
Last edited on
Ok thanks for the examples, and I do realize I have a couple separate gripes, some with C++, some with Microsoft, and some with the VisualStudio project.

Why the MS docs I looked at weren't as simple as the examples you provided is beyond me.

I'm off to work, but what is wx? Is it like boost?
Last edited on
Why the MS docs I looked at weren't as simple as the examples you provided is beyond me.


Probably because they were showing you how to use the time functions in WinAPI (platform specific code), and not the standard library (cross-platform portable code). WinAPI is Microsoft's library, after all... so it makes sense for them to document it.

I'm off to work, but what is wx? Is it like boost?


It's a widgetry library. It's like boost in the sense that it's another library that you have to download and install in order to use (it doesn't come pre-bundled). But it has a very different purpose from boost.


EDIT: to clarify, the full name of the lib is "wxWidgets", if you want to google it.
Last edited on
Yeah it's another library. wx is short for wxWidgets (unless he means another library) and is a meant for designing GUI's AFAIK. http://www.wxwidgets.org/ ah it seems to be what he is talking about http://docs.wxwidgets.org/3.0/classwx_date_time.html
That example is not C++ at all, that's a C program (just look at the file extension), using non-portable Microsoft APIs.

In C++, printing current time in "Fri Apr 25 01:19:27 PM" format looks more like this:
1
2
3
4
5
6
7
8
9
#include <iostream>
#include <iomanip>
#include <ctime>

int main()
{
    std::time_t t = std::time(nullptr);
    std::cout << std::put_time(std::localtime(&t), "%a %b %d %I:%M:%S %p") << '\n';
}

online demo: http://coliru.stacked-crooked.com/a/9ca072b87718b796

Granted, std::put_time was added to C++ only 3 years ago, to simplify the harder-to-use of std::time_put, but the boost libraries have been around for over a decade, where it was like this:

1
2
3
4
5
6
7
8
9
#include <iostream>
#include <boost/date_time.hpp>
namespace bpt = boost::posix_time;
int main()
{
    std::cout.imbue(std::locale(std::locale(),
                    new bpt::time_facet("%a %b %d %I:%M:%S %p")));
    std::cout << bpt::second_clock::local_time() << '\n';
}

online demo: http://coliru.stacked-crooked.com/a/b46712ef32a4fad5

If you don't care how the string is formatted, both are even simpler one-liners (but then so is C, the MSDN example was not written to show that)
Last edited on
If you're going to use C functions:
1
2
time_t now = time(0);
cout << ctime(&now);
I think most of this was fueled by ignorance, no offense intended.
Last edited on
One of the difficulties with C++ is that it is so big that ignorance is normal.
Many languages (and their runtimes) are easier to grasp because they really are so much simpler.

C++ lets you do anything. But it makes you do everything. Except when you know the libraries (plural!) enough to do what you want more easily.
I understand that the design of the language was based on speed over everything
This is a common wrongful thinking. It is designed for maximum flexibility.

The problem of the libraries is that they are not standardized (like name decoration) and hence it's difficult to add them to a project.
Although there have been many examples, my current beef is turning the current time into a string. This should be something as easy as:
string theCurrentTime = time::getLocalTimeAsString();

In C it's
1
2
3
time_t now;
time(&now);
printf("%s", asctime(localtime(&now)));

Is that so bad?

--and then the thing that really sets me off, the example uses the line:
printf( "%.19s %s\n", timebuf, am_pm );
which I can barely even figure out even after looking at
http://www.cplusplus.com/reference/cstdio/printf/

Yeah, printf is something else, but it's ubiqutous in C. Once you've learned it, you've learned it.

Speaking a little more broadly, and this is colored by the fact that I recently read the biography of Steve Jobs, this is such poor design.
Compared to what, modern languages? Probably, but we all stand on the shoulders of forgotten giants.

This functionality was written by elitists who've forgotten that not everyone has been writing C++ programs for a decade.
It wasn't any easier learning this stuff in the past either.

And if I add in the fact that the VisualStudio version was giving me an error message 4996 when I was using a simpler example, but that the MS docs for that error message couldn't point me to an easy-to-use fix for that problem, it's an example of how Microsoft is failing to deliver a product that is easy to use.
Point taken, but when's the last time Microsoft produced anything that's easy to use?

In summary, this is one example where doing a simple task in C++ requires way more knowledge than should be necessary. I should not need an in-depth understanding of the C++ time libraries, the differences between passing by reference and value, and the archaic formatting options of the printf function to get the local time.
I agree, but to be fair, as I've shown, you can format the current time in C without in depth knowledge either.
Point taken, but when's the last time Microsoft produced anything that's easy to use?


Just about everything MS produces is easy to use. It's partly why they're so successful.
Disch wrote:
Just about everything MS produces is easy to use.
Except for MSDN. I can't tell you how many times I've encountered completely unrelated and distant pages with identical names.
Last edited on
Yeah MSDN is clunky, I agree. And Bing isn't great.

I typically just use google to search MSDN for specific reference pages. I don't even try to navigate MSDN. Though the actual reference pages are fantastic. They're almost always very clear and go into great detail.


Really I was just countering the anti-MS hater attitude with my previous reply. =P
I think it is fair to say that C++ is a complicated looking language for a beginner because it seems to have no start point to finish point. C++ (as someone mentioned) allows you to do anything, but requires you to do everything. The reason for this is that C++ is simply a tool box, in this box you have...tools and most times these tools are not labeled properly (unlike in some languages).
Now supposing someone not familiar with these tools is told to build something, not only would they not know which tools to start using or which missing tools need to be "included", but they will not be able to visualize how the tools could come together to make what they need.
http://www.cplusplus.com/forum/general/142130/#msg750240
http://coliru.stacked-crooked.com/view?id=ddbc4b2fe17616ac

Compared to a language like python where almost every tool you need is immediately available and labeled properly, C++ requires a learning process that has low gains at first but pays off in the end

ex.
1
2
3
[[C++] std::cout << "Hello world" << std::endl;] vs 
[[PYTHON] print "Hello world"] vs 
[[C] puts("Hello world");]


Note that C and C++ involves the declaration of a main method, and the inclusion of a library
Last edited on
Stroustrup is a fan of verbosity (and so am I), so generally you are given all the tools to do things the verbose way and then you can make them terse later if you want. (Interestingly we're getting terse range-based for-loops in C++1z).

It takes a while to learn every part of a verbose statement, but at least you have something to look at to understand what's going on. You can look up what "std" is, what "cout" and "endl" are, what "<<" is, etc. But with python, you have a magical "print" statement/function depending on he version of the language you're using.

It's a matter of preference, and with C++ the preference was verbosity. Except with naming conventions ;p
Last edited on
MSDN is actually pretty great. The page for each function has:
* The function signature
* A description of each parameter, with the semantics of special values.
* The semantics of the return value.
* A remarks section, fleshing out the function in greater detail and often pointing out common pitfalls.
* The header that should be included to declare the function and the library, if any, that needs to be linked, plus the DLL that contains the actual code.
* Links to related functions.

I wish half of the documentation I normally use was this thorough.
The individual MSDN pages are great. Navigation is terrible. I just use Google like Disch.
Disch, helios, LB
+ 1

MSDN is notorious also for moving things around, so page references expire more regularly than fruit flies. My long-time strategy is to use Google's API to lookup the correct links for me. For example:

http://www.google.com/search?btnI=1&q=msdn+Console+Functions

That is unlikely to ever take you to the wrong page. (Your browser may not obey the redirect, though, forcing you to click the first link in the list of results...)


Re: tool ease of use
Current language design recognizes constructs and requirements that people use and need all the time and makes it easy to satisfy them.

C++, unfortunately, is befuddled by several problems:

1- It is an older language mixed with multiple paradigms. Radical language redesign would require another plus sign or letter or something. (Like D, which see.)

2 - It comes from C, which has as philosophy "use a library, Luke".

3 - There are untold masses of information on the net, written by people who don't know the correct way to do something, so it takes a lot of reading to learn to do things the Right Way. For example, Cubbi's example above shows how to use a locale facet to properly format the time into a string, but playing with facets is a deep, dark, scary art for most C++ programmers. (And who can blame them? Historically they are kludged by implementations into just barely functioning. Only recently have STL implementations begun to implement them correctly for all cases.)

4 - More advanced concepts are often required for reasoning about the 'easier-to-use' methods. (I'm currently reading a textbook that continually refers to stuff in later chapters, which makes the material significantly more difficult to learn. It's the same kind of problem for beginner and intermediate users in C++.)

To top it off, not all concepts are really a language issue. Messing with the time is a subject all its own. I'm currently stalled on the RNG portion of the FAQ, because the vast majority of RNG handling is wrong, and the correct way to do things is a little more involved than the 'easier' way listed in countless examples on the internet. But there is no One True Example to do it. (How does one write perfect code for a FAQ?)


tl;dr
It just takes time.


Meh.
Pages: 12