To go with Go or C/C++?

M

Melzzzzz

In C code that I have seen the functions return an int. Sometimes there
is enum returned. One value (often 0) indicates success and rest of the
values mean error codes. It is unlikely that whole string buffer and its
size as parameters will be devoted to error handling in real code.

Well, depending on scenario, sometimes message cannot be known
at top level. That's why I like exceptions more.
You get error message in object instead to propagate buffer.

Lot of C++ coding standards require throwing application-specific
exceptions. Such may be inherited from std::exception family but note
that in memory-constrained situation the bad_alloc will fly here instead
of runtime_error.

On Linux, (at least by default setup) one would never see bad_alloc,
because of overcommit.
If you want to improve performance of exception objects then you can
throw pointers to static exception objects or throw your own exception
objects that do not manage memory dynamically or derive such from
std::exception by overriding what() instead of having string constructor
arguments.

I don't have problems with strings and exception objects at all.
Actually c++ is very efficient so that one can relax when writing
code and code will work at acceptable performance.
In my early c++ days I used to optimise everything (computers were with
low memory and slow), now I really don't care, since programs just work.
Perhaps in some other language I would worry about performance
but not in c++.
 
T

Tobias Müller

Melzzzzz said:
On Linux, (at least by default setup) one would never see bad_alloc,
because of overcommit.

Overcommit does not help if you run out of address space. In a 32 bit
process you can only address 4GB of memory, regardless of how much physical
memory you have installed.

Tobi
 
R

Rui Maciel

Paavo said:
And that's all the reason needed to avoid C-style error handling. If the
error infomration consists of a single integer, then at best you get
Oracle-style "Error ORA-34567" which you have to look up somewhere, or at
worst you get Microsoft-style "Operation could not be completed".

What leads you to assume that C-style error handling ties you down to one of
those approaches?

If you have some string data, then it is at least possible that it might
make some sense to the end user, and most certainly it is helpful for the
developer to fix the problem (actually there should be two separate string
buffers, but this is another topic).

C-style error handling doesn't stop anyone from accessing and/or presenting
relevant information, and providing string data doesn't automatically
provide that either.


Rui Maciel
 
I

Ian Collins

Scott said:
Paavo Helde said:
And that's all the reason needed to avoid C-style error handling. If the
error infomration consists of a single integer, then at best you get
Oracle-style "Error ORA-34567" which you have to look up somewhere, or at
worst you get Microsoft-style "Operation could not be completed".

I honestly don't see why the app can't have an array of char *'s
itself, indexed by the "single integer", that can be printed
when the error is finally handled.

if ((fd = open(argv[1], O_RDONLY)) == -1) {
fprintf(stderr, "%s: Unable to open '%s': %s\n", argv[0], argv[1], strerror(errno));
return EXIT_FAILURE;
}

The 'array of char *s' can even be l10n or i18n as necessary (as in strerror(3)).

The use of errno here is an example, of course; an application can define
any set of error codes it likes for its error conditions and have the
equivalent of strerror(3) to generate an informative error message.

It is simple and the technique is frequently used in C. The downside is
the decision on what to do with the data is locked into the code at the
point of generation. If the same information is included in an
exception object, who ever catches the exception can chose how to use
the information. This is especially useful when the error is generated
from within a library: the application should decide how to report
errors, not the library.
One might argue that this approach is superior to throwing descriptive strings
since the descriptive strings are littered all over the place instead of being
all in one place (potentially in an external text file for each locale) which
aids in l10n/i18n efforts.

Which is why throwing an object that contains the information used to
generate the string is a superior approach. You can apply the same
internationalisation at a higher level. Not throwing a string also
reduces the risk of cyclic out of memory exceptions.
 
J

Jorgen Grahn

Overcommit does not help if you run out of address space.

Or if your process has an ulimit on data segment size set I suppose.
bad_alloc may happen less often now than 20 years ago, but it still
happens.

/Jorgen
 
S

Stefan Ram

I honestly don't see why the app can't have an array of char *'s
itself, indexed by the "single integer", that can be printed
when the error is finally handled.
if ((fd = open(argv[1], O_RDONLY)) == -1) {
fprintf(stderr, "%s: Unable to open '%s': %s\n", argv[0], argv[1], strerror(errno));
return EXIT_FAILURE;
}

Usually, one does not want to mix code for one system (here:
the filesystem) with code for another system (here: the
console, stderr).

What is »fprintf(stderr,« supposed to do in a GUI program or
in a library, where you do not know whether it will be
called from a console program or a GUI programm or a daemon
or whatever?
 
S

Stuart

I honestly don't see why the app can't have an array of char *'s
itself, indexed by the "single integer", that can be printed
when the error is finally handled.
if ((fd = open(argv[1], O_RDONLY)) == -1) {
fprintf(stderr, "%s: Unable to open '%s': %s\n", argv[0], argv[1], strerror(errno));
return EXIT_FAILURE;
}

Usually, one does not want to mix code for one system (here:
the filesystem) with code for another system (here: the
console, stderr).

What is »fprintf(stderr,« supposed to do in a GUI program or
in a library, where you do not know whether it will be
called from a console program or a GUI programm or a daemon
or whatever?

I know how the programmers in the company my wife works at would have
handled this: If you know that some function will print an error message
on stderr, you just have to redirect stderr to some string buffer,
invoke the function, and examine the string in the string buffer. Don't
forget to redirect stderr to the location it pointed to before you
invoked that function!

You see, there is a workaround for almost every design error ;-)

Regards,
Stuart

PS: Don't laugh, I have actually seen such code. It's incredible how
ingenious people can get when building such workarounds just because
they don't know how to design the problem better.

PSS: Or people know better, but cannot use the right implementation. You
can probably image my frustration when I had to "unlearn" all be C++isms
when I had to switch to ObjectiveC. I know that there is some kind of
"exceptions" in ObjectiveC but unfortunately the run-time will not
unwind the stack.
So Apple tells us ObjectiveC programmers to use exceptions only in cases
where the application is to be terminated anyway and use error codes
everywhere else. What a laugh.
 
J

Jorgen Grahn

I wouldn't say drastically. Valid, Useful C++ code can be very similar
to C code, with the primary difference being the visibility of data
members in 'class' aggregates vs. 'struct' aggregates.

But it wouldn't make use of the C++ language features, and C++
programmers wouldn't want to touch it. Doesn't sound very useful
to me!

/Jorgen
 
M

Melzzzzz

[email protected] (Scott Lurndal) said:
I honestly don't see why the app can't have an array of char *'s
itself, indexed by the "single integer", that can be printed when the
error is finally handled.
if ((fd = open(argv[1], O_RDONLY)) == -1) {
fprintf(stderr, "%s: Unable to open '%s': %s\n", argv[0],
argv[1], strerror(errno));
return EXIT_FAILURE;
}

Usually, one does not want to mix code for one system (here: the
filesystem) with code for another system (here: the console, stderr).

What is »fprintf(stderr,« supposed to do in a GUI program or in a
library, where you do not know whether it will be called from a
console program or a GUI programm or a daemon or whatever?
This was a flipping example. I even said as much.

If this makes you feel better:

if ((fd = ::eek:pen(argv[1], O_RDONLY)) == -1) {
d_logger->log("%s: Unable to open '%s': %s\n", argv[0], argv[1],
::strerror(errno));
return;
}

Where Logger::log is a pure virtual method in an abstract Logger class.

I use logger but not just for errors.
AppLog.debug(...);
AppLog.info(...);
AppLog.error(...);
AppLog.panic(...);
But I log exceptions, too ;)
 
I

Ian Collins

Scott said:
I honestly don't see why the app can't have an array of char *'s
itself, indexed by the "single integer", that can be printed
when the error is finally handled.
if ((fd = open(argv[1], O_RDONLY)) == -1) {
fprintf(stderr, "%s: Unable to open '%s': %s\n", argv[0], argv[1], strerror(errno));
return EXIT_FAILURE;
}

Usually, one does not want to mix code for one system (here:
the filesystem) with code for another system (here: the
console, stderr).

What is »fprintf(stderr,« supposed to do in a GUI program or
in a library, where you do not know whether it will be
called from a console program or a GUI programm or a daemon
or whatever?

This was a flipping example. I even said as much.

If this makes you feel better:

if ((fd = ::eek:pen(argv[1], O_RDONLY)) == -1) {
d_logger->log("%s: Unable to open '%s': %s\n", argv[0], argv[1], ::strerror(errno));
return;
}

Where Logger::log is a pure virtual method in an abstract Logger class.

This is still a case of the tail wagging the dog. It may be OK in a
single code base, but not for library code where the application writer
may have a different approach to error handling.
 
I

Ian Collins

Scott said:
I assume this is tongue in cheek. Most C++ programmers (the vast majority)
aren't similar to the half-dozen militant C++ progammers who routinely post
to this usenet newsgroup.

Most who have worked for my certainly are adventurous in their use of
the language. I've only worked with one team who just used C++ as a
better C and they were DSP programmers making their first tentative
steps away from C..
 
S

Stefan Ram

Melzzzzz said:
Well, yes, I agree that one need to know system. Depending on task and
system, hardware knowledge is required (or not).

»We won't go below the transistor level.«

(Quotation from a video of a Stanford lecture about
»Programming Methodology« I am just watching.)
 
J

Jorgen Grahn

I assume this is tongue in cheek.

Sorry, it wasn't.
Most C++ programmers (the vast majority)
aren't similar to the half-dozen militant C++ progammers who routinely post
to this usenet newsgroup.

I think people need to stop using "there's a C subset of C++" as an
excuse to write C in C++. It serves no purpose (other than perhaps to
trick naive managers) and I'd prefer if people/projects who do that
switch back to C instead.

There seem to be as many ways to write C++ as there are programmers,
but /some/ well-known features and techniques should be mandatory, and
I'm not talking about the C subset.

Surely that's not asking a lot? I don't suggest every piece of
software needs to use intricate object-oriented design, template
metaprogramming, the very latest C++11 features ... *that* would be
militant.

/Jorgen

PS. If I sound angry, it's because I see so much immature C++ in
production code. Written as if someone took a 2-day course in C++ in
1992 and vaguely remembers it. Granted, that's different from SL's
suggestion to (if I understand correctly) consciously use the C
subset.
 
Ö

Öö Tiib

So what would you say to people who want to use C++ in small embedded
systems, especially when safety or reliability is vital? In such
systems, you would not want to use dynamic memory (it is too
unpredictable), exceptions (they work as undocumented "gotos", are
painful to test, and can have massive overheads for small processors),
RTTI (a complete waste of space on small systems), lambdas (very
difficult for static analysis), virtual methods or multiple inheritance
(significant overhead on small processors), or almost anything from the
standard library.

Everybody who use C++ for something actually use only subset of the
features. That subset is formed for various reasons but basically it is
whatever they or their peers consider to be simple, efficient and safe
enough for the job. That is good since no one should use something
that they feel as dangerously complex, inefficient or unsafe for the job.

Now ... the subsets of different people differ because the conditions
and goals differ. Sometimes bad words (like "immature") are used in
discussions to describe such subsets of others. Others rightfully
respond back with ("unpredictable" or "waste of space"). As result
we ... C++ users ... must look rather unfriendly lot with each other
from side. ;-)
 
I

Ian Collins

Scott said:
That seems pretty rigid to me. C + classes is a quite useful subset of
C++ for a class of probles.

I agree. I do quite a lot of work in areas where there isn't any C++
run-time support (kernel land). Even without exceptions, RTTI and
chunks of the standard library, what's left of C++ is still a better C.
 
T

Tony

I agree. I do quite a lot of work in areas where there isn't any C++
run-time support (kernel land). Even without exceptions, RTTI and
chunks of the standard library, what's left of C++ is still a better C.

Calling what you describe "a better C", is, of course, just more jabber-wacky,
for C does not have the concept of classes and other C++ features. Only the
subset of C++ which pretty much is C with some improvements (not additions) can
be called "a better C", but that subset offers no significant benefit over C and
if you're looking for C features that aren't in C++, then you're out of luck.

It is OK to define various subsets of C++, but then trying to describe that
subset as "a better C", is too much of a stretch (of the character of C). It
really should be discouraged lingo, for C + classes is NOT "a better C", it is a
C++ subset, more appropriately. "C with classes" was a stepping stone to C++. C
did not evolve to C++. C is still C and C++ is an entirely different language.
 
T

Tony

Everybody who use C++ for something actually use only subset of the
features. That subset is formed for various reasons but basically it is
whatever they or their peers consider to be simple, efficient and safe
enough for the job.

Yes, the first step for using C++ on a project is to define what subset of C++
will be used and in what style. Basically creating a language from a huge
selection of parts. Surely many projects go awry for missing this key
preliminary step. Of course it takes a heavy-weight C++ developer who can think
outside of the box to perform such a role.

I haven't been on a C++ team project for ages, but I imagine that managers are
still trying to save a dime by simply hiring a bunch of programmers with C++ on
their resumes and hoping for the best. Stupid is as stupid does.
That is good since no one should use something
that they feel as dangerously complex, inefficient or unsafe for the job.

As if the average C++ programmer has the chops to make those determinations!
Now ... the subsets of different people differ because the conditions
and goals differ. Sometimes bad words (like "immature") are used in
discussions to describe such subsets of others. Others rightfully
respond back with ("unpredictable" or "waste of space"). As result
we ... C++ users ... must look rather unfriendly lot with each other
from side. ;-)

And from the front even... that's why I always come in with my guns out of their
holsters! ;)
 
T

Tony

C + classes is a quite useful subset of
C++ for a class of probles.

Sounds like a good idea for a website: a column on the left listing all of the
C++ features then project columns to the right (provided by users) showing with
check boxes which features of C++ were used. Or something similar. The
information would be interesting, to say the least.
 
T

Tony

(e-mail address removed) (Scott Lurndal) wrote in


You mean, "classes" like std::vector, std::map, std::string, and no C-style
arrays or pointer arithmethics in sight? In that case, this might be a
useful subset indeed.

STL seems like it would suck-in very much of C++. One could do much better with
other containers if they were seeking to avoid C++ features to a large degree.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,102
Messages
2,570,646
Members
47,247
Latest member
GabrieleL2

Latest Threads

Top